当前位置:首页 > 短网址资讯 > 正文内容

IM 消息可靠性及一致性的解决方案

www.ft12.com7年前 (2017-08-01)短网址资讯2510

即时聊天(IM)系统需要解决消息可靠性及消息一致性问题。

消息可靠性,简单来说就是不丢消息,会话一方发送消息,消息成功到达对方并正确显示;消息一致性,包括发送一方消息一致及会话双方消息一致,要求消息不重复,不乱序。

消息发送实现过程

消息发送一般的实现过程可以分为两个阶段:发送方发送消息,服务端接收,返回消息 ACK 给发送方;服务端将消息推送到接收方。判断消息发送是否成功主要依据第一阶段,即服务器是否接受到消息,消息状态可以分为三类:正在发送、发送成功、发送失败。其节点分别是:

1. 正在发送:发送方触发发送事件开始,到收到服务端返回消息对应 ACK 之前;

2. 发送成功:发送方收到消息对应 ACK 回复;

3. 发送失败:超过一定重发次数,未收到消息对应 ACK 回复。

消息发送流程图:

消息可靠性

重发机制

保证消息发送第一阶段消息成功发送的方法是设立重发机制,依据一定时长内是否收到消息对应 ACK,判断消息是否要重发,如果超过预设时长,就重新发送。当重发次数超过预设次数,就不再重发,判定该消息发送失败,修改消息发送状态。

会话记录检查

消息发送第二阶段服务端推送消息到接收方,如果连接断开,会丢失消息,所以要保证消息完整,就需要在建立连接后,根据上一条消息(已经 ACK)时间戳,获取会话记录,一次返回一段时间内所有消息。

另一种保证方法是加入定时轮询,检查消息完整性。

建立连接流程图:

两个问题

消息重发、会话记录检查需要考虑两个问题:消息是否会重复发送,消息顺序是否会被打乱。举两个例子:

1. 消息重发,如果丢消息的点在消息达到服务端之前,服务端并没有收到消息,发送方重新发送丢失消息,服务端接收成功,不会产生两条相同消息;而如果服务端接收到消息,返回 ACK 丢失,这时再发送一次相同消息,就可能造成消息重复。

2. 消息顺序,如果发送方连发三条消息,第一、第三条成功被服务端接收,第二条丢了,那第三条消息是否会被记录?如果这时第二条消息达到服务端,其顺序是在第三条时间之前还是之后(服务端一般都会给记录打一个时间戳)?

消息一致性

使用 uuid 消息去重

对于消息重发问题,可以给每条消息增加属性 uuid 作为消息唯一标识,重发消息 uuid 不变,前端根据 uuid 去重。

使用向量时钟进行消息排序

对于消息排序问题,因为在聊天中,消息的顺序对于发送方的表述有重要的影响,消息不完整或顺序颠倒都可能造成语意不连贯,甚至曲解。所以需要保证发送方发送消息顺序,而会话双方消息排序需要考虑实际情况。

在一般的认知里,状态是正在发送的消息,应该还没有被对方看到,只有发送成功的消息,才会被对方看到。但在实现中,消息发送成功是以服务器接收消息并返回 ACK 成功为判断依据,而不是被对方接收到。

那么就会出现这样一个问题,如果一条消息状态是正在发送,此时收到一条消息,那么收到的消息是在正在发送的消息之前还是之后?

这是一个上下文关系,关键问题是发送方是以哪条所见消息为依据发送消息的。

这里提供一种思路,借鉴分布式系统中的向量时钟算法。先简单描述向量时钟算法:

向量时钟算法用于在分布式系统中生成事件偏序关系,并纠正因果关系。一个系统包含 N 个节点,每个节点产生的消息体中包含该节点的逻辑时钟,整体系统的向量时钟由 N 维逻辑时钟组成,并在每个节点产生的消息体中传递。

向量时钟算法的具体实现:

1. 初始状态,向量值为 0;

2. 每次节点处理完节点事件,该节点时钟加一;

3. 每次节点发送消息,将包含自身时钟的系统向量时钟一起发送;

4. 每次节点收到消息,更新系统向量时钟,该节点时钟加一,其他节点对比每个节点本地保留的向量时钟的值和消息体中向量时钟的值,取最大值。

5. 节点同时收到多条消息,判断接收消息的向量时钟之间是否存在偏序关系

1. 如果存在偏序关系,则合并向量时钟,取偏序较大的向量时钟;

2. 如果不存在偏序关系,则不能合并。

  • 偏序关系:如果 A 向量中的每一维都大于等于 B 向量,则 A、B 之间存在偏序关系,否则不存在偏序关系。

对于消息排序,其实就是处理消息的上下文语境,决定消息之间的因果关系。参考向量时钟算法,假设有 N 个消息会话方,系统的向量时钟由 N 维时钟组成,向量时钟在各方发送的消息体中传递,并依据向量时钟排序,具体实现:

1. 系统向量时钟设为 (0, 0, …, N);

2. 节点发送消息,更新系统向量时钟,该节点时钟加一,其他节点不变;

3. 节点接收消息,更新系统向量时钟,该节点时钟加一;其他节点对比每个节点本地保留的向量时钟的值和消息中向量时钟的值,取最大值。

4. 依据消息体内系统向量时钟的偏序关系决定消息顺序:

1. 如果可以确定偏序关系,则根据偏序关系由小到大显示;

2. 如果多条消息不能确定偏序关系,则按照自然顺序(接收到的顺序)显示。

向量时钟在理论上可以解决大部分消息一致性的问题,但在实现中还需要考虑实际使用时的体验,这其中最需要关注的问题是:是否要强制排序,或者说,如果实际显示顺序和向量时钟之间的偏序关系不一致,是否要移动消息之间的顺序。

举个例子,在一个有多人的会话中,如果有一方网速特别慢,收不到消息,也发不出消息。在他看到的最后的消息之后,其他人已经开始新的话题,这时他关于上一个话题的消息终于发送成功,并被其他人收到,此时就存在这样一个问题:

这条关于上一个话题的消息是显示在最后,还是移到较早时间?如果显示在最后,但消息内容和目前的话题不相关,其他人可能会感到莫名其妙;如果把消息移到较早时间,那么这条消息可能不会被其他人看到,或者看到前面多了一条消息,会有种突兀的感觉。

IM 的场景很多,也很复杂,更多的时候需要从产品角度考虑问题。对于消息是否需要排序的问题,这里只提出一个比较通用的方案:建议会话中不强制排序,会话历史记录中按照向量时钟的偏序关系进行排序。

小结

对于 IM 系统消息可靠性及一致性问题,通过消息重发机制保证消息成功被服务端接收,通过会话记录检查保证收取消息完整,从而保证整个消息发送过程的可靠性;使用 uuid 消息去重,参考向量时钟算法进行消息排序,为保证消息一致性提供一种解决方案。

扫描二维码推送至手机访问。

版权声明:本文由短链接发布,如需转载请注明出处。

本文链接:https://www.ft12.com/article_368.html

分享给朋友:

相关文章

腾讯推行信用分的背后,或许是小程序电商的铺垫

腾讯推行信用分的背后,或许是小程序电商的铺垫

前言  最近腾讯信誉分开端进行灰度测验,引起了相当多的重视。  事实上,腾讯信征早已对外开放,而且推出时刻和芝麻信誉一样,同样是2015年。  只不过彼时腾讯只推出了信征报告,能够查询的内容也比较有限,其给出当前信誉较好、较差,以及当前排名...

汽车电商周报:解散风波与银行入股消息齐飞

【短网址资讯网】本周汽车电商与出行领域有10件大事值得关注。从汽车电商数据和平台的相关动作来看,汽车电商有惊无险,解散风波安全度过,业务创新还在继续。另外一个亮点是,本周互联网出行领域内关于摩拜被曝贪腐一事逐渐尘埃落定,网约车平台也拿到资质...

一条徐沪生比papi酱更有价值,短网址真的比直播更适合内容创业者吗?

一条徐沪生比papi酱更有价值,短网址真的比直播更适合内容创业者吗?

[ ft12短网址导读 ] 与papi酱的过气构成鲜明对比的是,短视频职业却越来越火,被称为直播之后的又一个内容创业风口,新老互联网巨头都争着往里面砸钱。用户为什么俄然对短视频产生了如此激烈的需求?真实能够依靠的盈利模式又是什么?...

当你老了,一生最后悔什么?

当你老了,一生最后悔什么?

全球统计前五名第一名:92%的人后悔年轻时努力不够导致一事无成所谓少壮不努力,老大徒伤悲,青春的大好时光总是流逝得那么快。而在青春岁月里,又常常碰到那么多的诱惑甚至陷阱,当你猛然醒悟时,也许白发早生,才发现自己竟然一事无成。多数人都遵循着一...

腾讯url.cn团队移动App的网络优化:短链接打开速度优化到原来15%历程

腾讯url.cn团队移动App的网络优化:短链接打开速度优化到原来15%历程

导读:在移动应用开发中,应用上线了只是一个开始,噩梦在后面:手机越用越卡为哪般?手机发烫是为何?谁偷走了用户的钱包?如何瘦成一道闪电?这些问题解决起来都是非常麻烦的,腾讯移动品质中心(url.cn)成立了专项测试团队来解决这些问题。最近几年...

没有结尾,菜鸟顺丰事件仅仅只个是开始

没有结尾,菜鸟顺丰事件仅仅只个是开始

[ 短网址资讯 ] 一场不大不小的争端,终究将顺丰的位置再一次提升,“炸出”了多位实力战友,在阿里身上失掉的利益,在他人身上能够“赚”回来,可是阿里失掉顺丰,质量快递方面怎样保障?没有诬蔑“灵通系”的意思,毕竟快递质量在...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。