分享

(7)高可用即时通讯架构

 quasiceo 2016-06-25
这是一个针对于高并发,高可用,移动端的架构。

在当前的资源环境配置下面,只要采用异步IO,一个几十个G内存的机器,所维持的连接数,单台可以达到几十万,所以在单台机器的连接数基本已经不存在瓶颈。

一、分离连接层与业务层
高可用即时通讯架构
连接层设计的核心是:1保持异步 2 让业务尽量简单
这样做的目的:
   为了不重启,不让用户断线。
    但是当需要跟新这个链接集群的代码的时候,还是会对连接层进行重启,而且刚刚启动起来的时候回去恢复所有的链接,造成的开销很大。而且启动的瞬间,如果做得不好,客户端的所有请求都会扑来,导致的结果就是自己对自己进行DDos。解决方法就是加入某台connector服务器需要重启,那就向客户端发出指令,让他们去别的connector。
    在消息中间件,只用开几十个线程用于转发消息就够了,因为前段来的消息是由缓冲的,消息中间件只用完成消息的转发业务就够了。
    客户端会不停地断线重练,比如用户进出一个房间,或者IOS客户端后台应用权限的问题等等环境因素影响。
    逻辑层其实是可以随便重启的,因为它只是去连接层的消息队列里面去消息来消费。逻辑层的一个核心业务会去验证用户的用户名 密码是否有效 以及session是否超期。 可以随时重启意味着代码可以随时跟新,可以在白天跟新代码。
    

二、传统通讯协议的缺陷

高可用即时通讯架构

常见协议 XMPP/SIP
缺点:流量大,不可靠,交互复杂
并没有考虑到移动端的特点,可以频繁地断线上线,并且在2G 3G 4G wifi 之间切换。
通常在地铁, 2G, 电梯等场所测出来的ping延迟都在10多秒左右,意味着往返一条消息需要半分钟。
高可用即时通讯架构
    而且移动互联网下面会经常出现半连接。就是经常会存在双方不知道对方已经断线了,而自己的消息都还正在传输或者是自己的端口还为对方打开着。经常会出现客户端或者服务器没有收到任何的IO异常,但是就是发出的消息会直接丢掉,tcp协议虽然是可靠地协议,但是只是维护消息的有序与安全,并非是说超时丢掉的那些数据,也就是没有收到对方握手的,都不要认为对方已经收到了。
    而且XMPP在握手过程中会有长达五次的消息来回,延迟非常巨大,一次往返加入需要20s,五次就需要1分多钟。在弱网络下几乎无法完成连接。常常会让用户认为自己网络不好,从而放弃这个应用。
    
三、面向移动端的通讯协议的设计

· 高效 :弱网络快色的收发,减少交互次数。
· 可靠 :不会丢消息
· 易于扩展 : 字段易于扩展,不会把每个字段干什么都定死。
    
    对于tcp来说,它是一个全双工的协议,即服务端发再多的数据给客户端,客户端发送再多的数据给服务端,都是互相不阻塞的。
    TCP协议中,经常把要发送的数据写到buffer里面,然后发送出去,另外一端收到得数据很有可能是不一样的,特别是在弱网络下面。比如一个比较大得数据,写进去以后,另外一端收到的buffer可能只是一个头部。所以在定义协议格式的时候可以定义一个标记位用于表示消息开始,然后定义一个长度来标示其数据的长度。然后读完了data之后再阻塞等待下一个标记位。
协议格式:
高可用即时通讯架构

以Redis协议为例
高可用即时通讯架构
比如发送一条指令 set name latermoon
需要先以星号开头,标记一个完整地包的开始,第一个3表示有3个参数,即set name 和latermoon。然后每一个参数用$符号隔开,并用长度+data的形式表示出来。

四、基于队列的消息存储与转发
·XMPP传统的做法
高可用即时通讯架构
    相当于一个先进先出的list,服务端的每一次send和客户端的recv都需要建立一次握手,往返成本是非常高的。传统的解决批量的问题可以把msg 3 4 5 6打包一起发出去,然后客户端一次性批量接受。这样虽然解决了往返的建立连接的成本问题,但是却造成一个新的问题。有可能3 4 5 6的消息打包在一起非常大,在弱网络下面要成功地传输一个很大的包成功率是非常低得,很有可能导致反复地tcp超时重传,导致这个包在弱网络下面无论如何都接收不了。弱网络下超时时间一般根据经验去设定,通常为30s。
下面这个图表述的时相同的意思,即每一次往返都有一次建联断连的开销。
高可用即时通讯架构

    传统的通信这样设计是因为网络比较好,一旦传输出现异常,会立即反应出来。
    这样还有一个缺点就是高可用方面也会出现问题。服务器端必须维护消息队列的状态,假如服务器再发送完某一条消息后挂了,下一次重启的时候该从哪里继续,也是一个很麻烦的事情。
    
五、通讯协议的优化:
高可用即时通讯架构

    优化会引入消息的版本号,版本号是一个唯一的递增的序号。可以考虑不用list来存考虑有sorted set来存放消息。

    当服务器有新的消息需要推送给客户端的时候,需要先发送msg-psh通知客户端,得到客户端拉消息的确认msg-sync过后,客户端开始同步消息。这个时候消息的顺序维护已经交给了客户端,也就是说客户端向哪一个connector去拉消息都是等效的。服务器收到消息后以流的形式将消息打给客户端,由于tcp是双工的,客户端可以不定期的返回它所收到的消息的最新版本号。这样就可以实现两边同时工作互不干扰。
    如果社交软件里面有群的话,基本必须要这样做。

六、其它需要考虑的问题
· DNS劫持
    在国外运营商不会劫持你得DNS,但是国内情况不同,很多运营商会不定期的劫持一些DNS,或者某个IP,导致客户端无法连接到某些服务器。
    解决方法:每次客户端连上服务器,就先去拉去下一次连接上来可用的ip地址列表。

· 链路问题
    有的时候ip 是可用的,但是由于链路问题,就是连接不上。这个时候需要客户端来检测并找到一个最优的服务器以取得连接。

· 图片与音频视屏的传输
    前面的协议主要是用于传输一些比较轻量的数据,对于传输一些比较大的数据,需要单独建立一个TCP的连接。


参考链接:http://www./cn/presentations/high-availability-instant-communication-architecture

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多