IT学习站-137zw.com

more +资源更新Forums

more +随机图赏Gallery

2020一级造价工程师交通课件视频讲义百度云网盘下载2020一级造价工程师交通课件视频讲义百度云网盘下载
大神教你玩转excel高效人生大神教你玩转excel高效人生
开运网付费开源商业版|风水起名八字算命易经周易源码开运网付费开源商业版|风水起名八字算命易经周易源码
李梦娇2020年《公共基础知识》事业尊享套餐李梦娇2020年《公共基础知识》事业尊享套餐
马哥Linux高端运维云计算就业班 强烈推荐马哥Linux高端运维云计算就业班 强烈推荐
Flutter视频教程_Flutter仿京东商城项目实战视频教程Flutter视频教程_Flutter仿京东商城项目实战视频教程

《即时消息技术剖析与实战》学习笔记4——IM系统如何保证消息的可靠性

《即时消息技术剖析与实战》学习笔记4——IM系统如何保证消息的可靠性

[复制链接]
123456833 | 显示全部楼层 发表于: 2019-11-14 14:40:00
123456833 发表于: 2019-11-14 14:40:00 | 显示全部楼层 |阅读模式
查看: 199|回复: 0

你还没有注册,无法下载本站所有资源,请立即注册!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
IM 系统中,保证消息的可靠投递主要体现在两方面,一是消息的不丢失,二是消息的不重复。
一、消息不丢失

消息丢失的原因

首先看一下发送消息的流程,如下图所示:

图片来源于《即时消息技术剖析与实战》第 04 讲
用户 A 发出的消息,先到达IM服务端(步骤1),由服务端暂存(步骤2),成功后,服务端将成功的结果返回给用户A(步骤3),同时将消息推送给用户B(步骤4)。
在这个过程中,丢失消息有以下几种情况:
1)步骤 1 因为网络不通等原因导致用户A把消息发送到IM服务器失败;
2)步骤 2 IM服务器存储消息失败;
3)步骤 3 用户A在超时时间内未收到IM服务器返回的结果;
4)步骤 4 由于IM服务器断电等原因导致消息未能成功推送给用户B(但步骤 3 用户A可以收到IM服务器返回的响应成功结果);
5)步骤 4 消息成功推送给用户B的设备,但用户B的设备因为一些原因如设备写入本地DB失败等,也会导致消息丢失。
前三种情况,用户A将被提示消息发送失败;后两种情况,用户B未收到消息。
消息丢失的解决方案

大部分场景中,业务层ACK确认机制 + 消息重传机制 + 消息完整性检查,能解决消息丢失的问题。
1.业务层的ACK确认机制和重传机制
ACK是确认字符(Acknowledge character)的意思,TCP协议默认提供了ACK机制,如果接收方成功接收到数据,就会回复一个ACK数据,表示发送方发出的数据已确认接收无误,在“三次握手”、“四次挥手”中经常见到。
ACK确认机制:TCP传输时将每个字节的数据都进行编号,即序列号。TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答,也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据。这也是TCP传输可靠性的保证之一。
重传机制:发送方发送一部分数据后,都会等待接收方发送的ACK报文,并解析ACK报文,判断数据是否传输成功。发送方迟迟收不到ACK报文的原因可能有两个:
1)数据在传输过程中由于网络原因等直接全体丢包,接收方没有接收到;
2)接收方接收到了响应的数据,但是发送的ACK报文响应却由于网络原因丢包了。
超时重传机制就是发送方在发送完数据后等待一个时间,如果在超时时间内没有接收到ACK报文,就重新发送数据。如果是上述的第一个原因,接收方收到二次重发的数据后,便进行ACK应答。如果是第二个原因,接收方发现接收的数据已存在,就直接丢弃,仍旧发送ACK应答。
业务层的ACK确认机制参考了TCP的ACK确认机制,其策略是IM服务器在推送消息时,携带一个标识SID(安全标识符,类似TCP的sequenceId),推送出消息后会将当前消息添加到“待ACK消息列表”,客户端B成功接收完消息后,会给IM服务器回一个业务层的ACK包,包中携带有本条接收消息的SID,IM服务器接收后,会从“待ACK消息列表”记录中删除此条消息,本次推送才算真正结束。
业务层的消息重传机制也参考了TCP协议的重传机制,IM服务器的“等待ACK队列”一般会维护一个超时计时器,一定时间内如果没有收到用户B发回的ACK包,就从“等待ACK队列”中重新拉取并进行重推。
为什么有了TCP协议本身的ACK机制,还需要业务层的ACK机制?
这是因为TCP属于传输层,而IM服务属于应用层。TCP的ACK保证网络传输层的可靠性,即消息是否送达,但不能保证数据能够被应用层正确可靠处理;业务层ACK进行消息是否送达和是否正确处理的逻辑,达到不丢消息、消息不重复的目的。
2.时间戳比对检查消息完整性
在上面列举的丢失消息的第 4 种可能性中,如果步骤 4 IM服务器将消息推送出去后就宕机了,而这条消息又因为某些原因丢失了,服务器由于宕机无法触发重传机制,导致用户B收不到该消息。可以采取“时间戳比对”机制进行完整性检查。

图片来源于《即时消息技术剖析与实战》第 04 讲
时间戳比对过程如下:
1)IM服务器给用户B推送msg1,同时带上一个最新时间戳timestamp1。用户B收到msg1后,更新本地的时间戳为timestamp1;
2)IM服务器给用户B推送msg2,同时带上一个最新时间戳timestamp2。由于某种原因,用户B和IM服务器的连接断开,导致msg2没有成功推送到用户B;
3)用户B和IM服务器重新建立连接后,将本地的时间戳timestamp1发送给IM服务器,IM服务器将时间戳大于timestamp1的所有消息全部发送给用户B,同时带上时间戳timestamp2(这里假设时间戳大于timestamp1的消息只有msg2,如果有msg3、msg4等多条消息,应取最新消息的时间戳);
4)用户B收到msg2后,更新本地的时间戳为timestamp2。
通过这样的比对可以有效解决消息丢失的问题。但时间戳由于有时钟不同步、或者一个时间戳内多条消息的可能性,存在误差,因此可以使用全局的自增序列版本号来代替。
二、消息不重复

消息重复的原因

在上面列举的丢失消息的几种可能性中,第 3 种可能性存在一种场景,步骤 4 将消息成功推送给用户B,但步骤 3 因为某些原因导致超时、用户A收不到响应,这个时候会触发重传机制,用户A重新发送请求,用户B可能会收到重复消息。
消息重复的解决方案

IM服务器推送消息时,携带一个Sequence ID,这个Sequence ID在本次连接会话中唯一,同时针对同一条消息不变。当接收方接收到消息后,会根据这个Sequence ID来进行业务层的去重,可以有效地保证消息的不重复。
三、小结

通过业务层的ACK机制、重传机制和完整性检查,可以有效解决推送过程中消息丢失的问题;
通过客户端的去重机制,可以有效解决消息重复的问题。

来源:http://www.137zw.com
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
137zw.com IT学习站致力于免费提供精品的java技术教程和python技术教程,CCNA书籍/资料/CCNP书籍/资料教程/CCIE书籍/资料/H3C学习/认证/一级建造师考试/微软学习/认证/包括基础教程和高级实战教程,同时也提供分享网站源码下载和互联网相关一系列的技术教程,我们想做的就是让知识分享更有价值!(IT学习站官方唯一域名地址:www.137zw.com 请谨防假冒网站!)本站所有资源全部收集于互联网或网友自行分享,分享目的仅供大家学习与参考,如无意中侵犯您的合法权益,请联系本站管理员进行删除处理!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

浙ICP备19022368号-1|Archiver|手机版|IT学习站-137zw.com

GMT+8, 2020-9-20 23:34 , Processed in 0.208847 second(s), 45 queries .

快速回复 返回顶部 返回列表