对于一个即时通信服务器来说,在用户量少的时候,一台服务器就足以提供所有的服务。而这种架构也最简单,举个例子,用户A与用户B互为好友,A向B发消息,服务器接收到消息时,解析出接收消息的人,直接转发给B即可。可是当用户数量越来越多时,一台服务器已经无法所有用户的需求,这时就要进行服务扩容,进行分布式部署
如图所示,不同的用户可能登录到不同的服务器上,那么用户A给用户B发消息时,服务器收到消息,首先判断B是否也登录在本服务器上,如果是,那么直接转发消息即可。如果B不在本服务器上,那应该往哪里转发这条消息呢?最简单的做法就是向服务器集群中的其他服务器广播这条消息,对于每个收到这条消息的服务器,首先判断消息的目的用户是否登录在自己身上,如果不是,直接忽略该消息。如果是,那么向目的用户转发该消息。固然,这种暴力粗犷的做法是最简单直接的,但是会产生很多无效的消息转发,对于服务器性能产生很大的影响。曾看过蘑菇街开源的即时通信软件Teamtalk的代码,服务器就是这种实现方式。其服务器架构如下:
不同的msg服务器连接到同一台route server上,所有msg服务器之间的转发全部通过route server。这无疑会加重route server的负载。即时msg server部署的再多,根据木桶理论,一个系统的性能是由其最薄弱的环节所决定的。所以也注定这样的架构,其系统容量也是有限的。那么如何改善这种系统呢,很明显服务器之间的消息转发不能直接全部广播,而应该有一套明确的路由系统,即服务器在转发消息时,应该知道这条消息应该转发到哪一台服务器,这样就不需要每条消息都在所有服务器之间广播了。
那么如何实现这样一套路由系统呢?
简单的做法是,每个用户上线时,通过其连接的msg server向其他所有msg server广播自己的登录信息,告知其他服务器自己登录在哪台服务器上面。这样当某个用户向其好友发消息时,首先通过好友id查看其登录的msg server。如果好友与自己是同一台服务器,那么直接转发即可;如果不是,服务器向route server发送转发该消息,并且带上目标msg server的id.这样route server 收到消息后,解析出目标的msg server,进行一次转发即可,省去了大量的广播消息。这种方式虽然解决了广播消息的问题,但是在每台msg server上都要保存所有用户的路由信息。当所有用户都登录时,几乎就退化成了单点模型,msg server肯定承受不了。
延伸阅读
- ssh框架 2016-09-30
- 阿里移动安全 [无线安全]玩转无线电——不安全的蓝牙锁 2017-07-26
- 消息队列NetMQ 原理分析4-Socket、Session、Option和Pipe 2024-03-26
- Selective Search for Object Recognition 论文笔记【图片目标分割】 2017-07-26
- 词向量-LRWE模型-更好地识别反义词同义词 2017-07-26
- 从栈不平衡问题 理解 calling convention 2017-07-26
- php imagemagick 处理 图片剪切、压缩、合并、插入文本、背景色透明 2017-07-26
- Swift实现JSON转Model - HandyJSON使用讲解 2017-07-26
- 阿里移动安全 Android端恶意锁屏勒索应用分析 2017-07-26
- 集合结合数据结构来看看(二) 2017-07-26
学习是年轻人改变自己的最好方式