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

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

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

即时聊天(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

分享给朋友:

相关文章

因央行监管严,微店或将不能用微信支付了

因央行监管严,微店或将不能用微信支付了

【FT12短网址】2017年6月15日上午,不少网友反应在口袋购物旗下微店(下简称“微店”)内已无法运用微信付出进行付款。亿邦动力网测验在微店内下单采购时发现,在挑选付款方法的页面,微信付出现已处于灰色不行选中情况,下面的赤色提示文字显现“...

如何在 Linux 下大量屏蔽恶意 IP 地址

如何在 Linux 下大量屏蔽恶意 IP 地址

很多情况下,你可能需要在Linux下屏蔽IP地址。比如,作为一个终端用户,你可能想要免受间谍软件或者IP追踪的困扰。或者当你在运行P2P软件时。你可能想要过滤反P2P活动的网络链接。如果你是一名系统管理员,你可能想要禁止垃圾IP地址访问你们...

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

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

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

低质量的社交不如高质量的独处

低质量的社交不如高质量的独处

来源:视觉志(QQ_shijuezhi)不知道你有没有过这样的感触:一群人狂欢时的孤独,有时会胜过一个人独处。与其浪费时间精力,去做一些无用的社交,倒不如学会如何与自己相处。独处,当然,是一个人。你要耐得住寂寞,专注自己正在做的事。如果是在...

文旅IP与住宿业融合:无IP不文旅,有IP则称王

文旅IP与住宿业融合:无IP不文旅,有IP则称王

[ FT12短网址 ] 生命在于有意义和有意思,已经成为很多人的价值观和生存观。他们渴望一个更精彩的生存方式,而不仅仅是填饱肚皮。这就催生了各种文化娱乐产业的诞生,在旅游行业,就是文旅产业。图片来自“123rf.com.cn”大约...

一个40岁华为男的自白:作为前IBM员工,除了钱,我为什么要来华为“受虐”

我离开“我摸”(IBM的江湖俗名)加入华为的时候,老板、同事、同学、朋友都十分惊讶的问我为什么。当时总是很装逼的说:“换个环境,我想看看自己的career。”实际上入职后的好几年里,我还在问自己到底为什么来华为。别笑我如此纠结,当年华为的名...

发表评论

访客

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