QTalk是如何保证消息稳定送达的
作者:互联网
1. 前言
什么是IM? IM,是 InstantMessaging(实时传讯)的缩写。这是一种可以让使用者在网络上建立某种私人聊天(chatroom)的实时通讯服务。 IM具有实时,可群体对话,多媒体消息,消息一般性优先级,消息可回溯性等几个基本特性。
在本文中,你可以从原理上了解到 Qunar自己的im —— QTalk是如何保证消息稳定送达的,以及目前QTalk在保证消息稳定送达的瓶颈是什么。
按照惯例,首先介绍QTalk。
2. QTalk是什么
QTalk 是Qunar在2015年开始正式使用的内部沟通工具,由我们团队进行开发设计维护。 最初打造她的原因仅仅是因为腾讯的RTX频繁出现几次公司级的问题。另外,RTX没有移动版本,再加上它的授权问题也日益凸显。 后来随着开发的不断深入和移动端的加入,QTalk已经改变了Qunar的办公方式,也逐渐形成了QTalk 家族. 现在QTalk以及相关衍生版本(QChat)正在全力为Qunar公司员工以及业务提供多种多样的IM服务。
3. im为什么会丢消息
既然提到稳定送达,就意味着im会有丢消息的可能。im的技术场景跟我们目前常用的业务实现场景不同,它依赖内部保持的一条长连接进行双工通信以达到实时性。 基于长连接的业务容易受如下几个问题影响:
网络环境复杂,或是经常需要切换网络,比如我们挂***;
同样是网络环境复杂,手机发生网络切换、进入信号弱的区域,或者基站连接数太高了之后导致延迟高的时候;
异常报文导致主动断开连接;
PC机休眠后网卡断电、硬盘停止工作等等。
当遭遇以上场景后,im便不可避免的需要进行重连。一旦发生重连,在重连完成的过程中出现的消息便无法准确的出现在程序中,于是就产生了丢消息的问题。 (长连接重连是整个im实现中比较复杂的部分,需要考虑的状态比较多,这里掠过不表。) 其实,连接重建是时时出现的,丢消息却不能时时出现。我们能在绝大多数场景下可以进行完整的QTalk对话主要还是依赖本文的内容对内容进行修正后保证的。
4. 保证消息稳定送达的机制
我们在保证消息稳定发出、稳定运输、和稳定送达这3方面做了以下工作:
消息发送端在发送的时候尽可能保证发送成功;
发送成功的消息可能会由多次发送来保证的,需要保证消息唯一;
后台尽可能缩短路由流程,以保证节点间丢失率尽可能小;
后台尽可能使用队列来保证后台节点间的消息稳定送达;
接收端保证连接稳定,否则主动断开连接并主动获取历史记录。
消息送达机制
消息发送时真实的状态是比较复杂的。QTalk关注了以下几点:
如流程图所示,当且仅当消息发送且收到服务器回执之后,消息才真正被认为发送成功了;
当消息发送实际上是成功了,没在规定时间内收到服务器的回执,消息也会被认为发送失败
所有失败了的消息,要么进入重试机制进行有限的重试(无逻辑的重试会导致死循环),要么显示消息发送失败,让用户主动选择重发;
消息接收机制
消息稳定接收依赖网络状态检查,而以下的内容会触发连接检查:
定时心跳检测
任何一次网络请求超时都会导致连接检测
当连接真实断开,或者由于网络不足够通畅而被Qtalk断开连接后,客户端会首先重连、获取令牌后直接sync服务端的未能收取的消息,以保证消息到达,这个时间是非常短的。
5. 进阶:保证多个客户端进行消息同步的机制
QTalk不同于微信,需要对多个可登录的客户端做消息同步,也就是说,同一个用户在同时登录了PC和手机客户端的时候,在任意一个客户端上做的操作会同步到另外一个客户端上。 然而这里并不打算展开这个话题,只是简单介绍一下,在多个同一账号客户端登录时如何保证消息同步 要想做到这一点,至少需要:
各客户端独享自己的长连接与服务端保持通信;
在接收消息的时候,根据服务器设定选择下行到这个用户的某个特定连接上,或者是他的全部连接,QTalk选择的是默认后者;
在某一端发生消息发送时,服务器会下发特殊的抄送消息,这个抄送消息会被其他登录着的同账户客户端收到,并解析成发送消息;
如果发生连接断开,做跟上面介绍的同样的操作进行消息补偿。
至此,QTalk保持消息高效送达的机制基本就介绍完了。
6. 继续提升
多级消息送达回执
目前只有发送消息有回执,它保证了消息是否真实发出去的状态是准确的。 发送者非常清楚消息已经通过发送端到达了服务端,然而服务端是否下行到对方,由于没有回执,无可知晓。 目前这个能力暂时还未实装的原因,是因为单节点后台,其到达率可以达到100%。 可以理解为由于Qtalk后台比较轻量级,这个需求就变成了一个产品需求而非技术需求,进而降低了优先级,在未来的版本里会提供这样的能力。 而像QChat(服务于Qunar自营业务)这样级别的平台需要这样的功能。
补充异常网络状态
目前兼容了绝大多数网络状态下可能出现的问题,其实长连接面对的挑战还是网络状态多导致的某些场景下不能覆盖的问题。像境外网络的场景目前我们处理的较少,虽然能用,但是效果肯定是不如国内的。
平衡连接重建的频度
目前仅有几个核心请求会在失败之后重建连接,未来会在更多的请求上加入连接检测重建,但是这个需要平衡整体的效率以及使用手感。
标签:发送,保证,消息,客户端,连接,QTalk,送达 来源: https://blog.51cto.com/u_15127643/2773418