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

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

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

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

分享给朋友:

相关文章

手机QQ打开网址自动跳转浏览器php源码

通过一段代码让网址在手机QQ内被点击时自动打开默认浏览器跳转,但是这段代码并不完美,经过几个后缀不同的域名的测试,只有访问.cn或者.com域名时才能正常的跳转。这个代码适用于很多方面,例如使被QQ管家拦截的域名在手机QQ内通过跳转能够得到...

短网址系统如何面对高并发进行优化?

短网址系统如何面对高并发进行优化?

短网址 望文生义,即是将长网址缩短到一个很短的网址,用户拜访这个短网址能够重定向到原本的长网址(复原)。这么能够到达易于回忆、变换的目的,常用于有字数约束的微博、二维码等场景。开篇先抛出几个疑问,假如咱们自个去完成会怎样完成这个看...

FT12短网址解读阿里Q4财报:将增加短网址投入成本

阿里巴巴周五收涨,盘中股价创历史记录。公司周四发布最新财报,财报显示,阿里巴巴集团第四财季收入为385.79亿元人民币,同比增加60%;阿里中心电商事务收入同比增加47%,运营赢利达165亿元;包括阿里云以及数字媒体和文娱事务等新式事务收入...

花式共享还是变相租赁,共享经济下一步怎么走?

共享经济概念持续火热前提下,生活中的很多物品纷纷带着“共享”的帽子进局。比如共享篮球、共享雨伞、共享充电宝等产品纷纷面世,日前,共享篮球平台“猪了个球”宣布完成千万级Pre-A融资;共享充电宝“街电”获得聚美优品3亿元的投资;“小电”获得B...

互联网巨头进军影视业:阿里、腾讯比亚马逊差在哪里

互联网巨头进军影视业:阿里、腾讯比亚马逊差在哪里

砍柴网 / 高洪浩 1982年,电影《星际迷航2》为世界影史贡献了第一个完全由计算机创造的景象:一个导弹击中星球,并使其爆炸。这个完全脱离现实而创造出的60秒钟画面,让好莱坞成为了“造梦...1982年,电影《星际迷航2...

真正独立的女性是少数,其他的都是九尾妖狐

真正独立的女性是少数,其他的都是九尾妖狐

“你给我爱情就好了,面包我自己挣。”01我朋友圈里便有这样一个“独立”的女孩。她漂亮且开朗,懂得如何跟男人相处,给他们若即若离的感觉,游刃有余,张弛有度。男人们在她的石榴裙下拜服,却从未有人能一亲芳泽,但他们总愿意为她消费,好像只要银行卡刷...

发表评论

访客

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