《即时消息技术剖析与实战》学习笔记5——IM系统如何保证消息的一致性
一、什么是消息一致性
消息一致性指的是消息的时序一致性,即消息收发的一致性。如果不能保证时序一致性,就会造成聊天语义不连贯,引起误会。
对于点对点的聊天场景,时序一致性保证接收方的接收顺序和发送方的发出顺序一致;对于群聊场景,时序一致性保证所有接收人看到的消息展现顺序一致。
二、消息一致性的难点
1.多发送方、多接收方、服务端多线程并发处理情况下,无法保证时序一致性。
2.分布式环境下,多个机器的本地时钟不一致,没有“全局时钟”,不能用“本地时间”保证时序的一致性。
三、消息的一致性的实现
1. “全局序号生成器”作为“时序基准”
为什么不以客户端(发送方)的本地序号/本地时钟作为“时序基准”?
如果以发送方的本地时钟作为时序基准,发送方发送消息时,将消息本身和本地的时间戳或一个本地维护的序号发送到IM服务端,IM服务端再将这个消息和时间戳或序号发送给消息接收方,消息接收方根据这个时间戳或序号进行排序。
若发送方随时调整时钟,会导致时间戳回退;若发送方重装应用,会导致序号清零,从而回退。
而针对多发送方场景,如群聊和多点登录,存在同一时钟的某个时间点、多条消息发送给同一接收对象的可能。比如一个群聊内,用户A先发言、用户B后发言,但如果用户A的时钟比用户B的时钟慢,已发送方的本地时钟作为“时序基准”就会出问题;再比如微信在手机、电脑上同时登录,两台设备可以给某一接收方发送消息;若设备的本地时钟不一致,接收方可能会出现消息不连贯的问题。
为什么不以服务器的本地时钟作为“时序基准”?
如果以IM服务器的本地时钟作为时序基准,发送方将消息发送到IM服务端,IM服务端依据自身服务器的时钟生成一个时间戳,然后将消息和时间戳一起发送给消息接收方,消息接收方根据这个时间戳进行排序。
一旦IM服务集群化部署,就会出现多台服务器本地时钟不一致的问题。虽然多台服务器可以通过NTP时间同步服务,但依然存在一定的时间误差。
将“全局序号生成器”作为“时序基准”,可以解决每条消息没有标准“生产日期”的问题,按着实现方式可以分为两类,一是支持单调自增序号的生成,如Redis的原子自增命令incr、MySQL的自增ID,二是分布式时间相关的ID生成,如snowflake算法、时间相关的分布式序号生成服务等。
对于群聊和多点登录的场景,只需要保证一个群的消息有序即可,无需全局的跨多个群的绝对时序性。每个群聊有其独立的“ID生成器”,可以通过哈希规则路由到对应的主库实例上,降低多个群聊共用一个“ID生成器”的压力。
2.消息整流
当 IM 服务端接收到消息后,若 IM 服务器是集群化部署,可能因为服务器性能的差异,导致后收到的消息先发出去;又或者多线程处理消息的流程不能保证先到达的消息先发送出去,从而使接收方收到的消息顺序有误,因此需要消息整流。消息整流又分为服务端包内整流和客户端(接收方)整流。
服务端包内整流
比如实现离线推送,当用户上线,网关机会通知业务层用户已上线,业务层就会把该用户的多条离线消息 pub 给这个网关机的 Topic,网关机再把收到的多条消息通过长连接推送给用户。

图片来源于《即时消息技术剖析与实战》第 05 讲1)生产者为每个消息包生成一个packageID,为包内的每条消息加个有序自增的seqID;
2)消费者根据每条消息的packageID 和 seqID 进行整流和排序;
3)执行模块只有在一定超时时间内完整有序地收到所有消息才执行最终操作,否则根据业务需要触发重试或直接放弃操作。
消息接收端整流
1)发送方发送消息时,连同消息和序号一起发送给接收方;
2)接收方接收到消息后,先去查找上一条消息的序号,然后比对收到的序号和上一条消息的序号;
3)如果收到的消息序号大于上一条消息序号,直接追加;反之则去查找小于该序号的最大消息序号,并追加到其后。
四、参考
消息时序一致性还可以参考58沈剑大佬的文章:消息“时序”与“一致性”为何这么难?,又会有不一样的收货。
《即时消息技术剖析与实战》学习笔记5——IM系统如何保证消息的一致性的更多相关文章
- 《即时消息技术剖析与实战》学习笔记4——IM系统如何保证消息的可靠性
IM 系统中,保证消息的可靠投递主要体现在两方面,一是消息的不丢失,二是消息的不重复. 一.消息不丢失 消息丢失的原因 首先看一下发送消息的流程,如下图所示: 消息.可以采取"时间戳比对&q ...
- 《即时消息技术剖析与实战》学习笔记6——IM系统如何保证消息的安全性
在消息产生.流转的各个环节中,需要保证消息传输安全性.消息存储安全性.消息内容安全性. 一.消息传输安全性 消息传输的重要防范点有两个,一是访问入口安全,二是传输链路安全. 1.HttpDNS保证访问 ...
- 《即时消息技术剖析与实战》学习笔记3——IM系统如何保证消息的实时性
IM 技术经历过几次迭代升级,如图所示: 从简单.低效的短轮询逐步升级到相对效率可控的长轮询: 全双工的 Websocket 彻底解决了服务端的推送问题: 基于 TCP 长连接衍生的 IM 协议,能够 ...
- 《即时消息技术剖析与实战》学习笔记1——IM系统的架构
一.IM的应用场景 聊天.直播.在线客服.物联网等所有需要实时互动.高实时性的场景,都需要应用到 IM 技术.
- 《即时消息技术剖析与实战》学习笔记12——IM系统如何提升图片、音视频消息发送、浏览的体验
IM系统如何提升用户发送.浏览图片和音视频消息的体验呢?一是保证图片.音视频消息发送得又快又稳,二是保证用户浏览播放图片.音视频消息时流畅不卡顿. 一.提升用户发送图片.音视频的体验 1. 多上传接入 ...
- 《即时消息技术剖析与实战》学习笔记11——IM系统如何保证服务高可用:流量控制和熔断机制
IM 系统的不可用主要有以下两个原因: 一是无法预测突发流量,即使进行了服务拆分.自动扩容,但流量增长过快时,服务已经不可用了: 二是业务中依赖的这些接口.资源不可用或变慢时,比如发消息可能需要依赖& ...
- 《即时消息技术剖析与实战》学习笔记7——IM系统的消息未读
一.什么是消息未读 消息未读包括会话未读和总未读.前者指的是当前用户和某一聊天方的未读消息数,后者指的是当前用户的所有未读消息数,也就是所有会话未读的和.比如用户A收到用户B的2条消息,还收到用户C的 ...
- 《即时消息技术剖析与实战》学习笔记8——IM系统如何保证长连接的可用性:心跳机制
假设有以下突发意外情况: 用户进入信号不好的地方,手机没有网络信号了 上网的路由器突然掉线了 这个时候,比如微信发消息,消息就会转圈圈,甚至变成红色叹号-- 上面情况都会导致"长连接&quo ...
- 《即时消息技术剖析与实战》学习笔记9——IM系统如何支持消息的多终端漫游
一.什么是多终端漫游 多终端漫游是指:用户在任意一个设备登录后,都能获取到历史的聊天记录.如:QQ 默认漫游 7 天的聊天记录,开通 VIP 会员可漫游 30 天,开通 SVIP 会员可漫游 2 年. ...
随机推荐
- 不等"金九银十",金风八月,我早已拿下字节跳动的offer
字节跳动,我是在网上投的简历,之前也投过一次,简历都没通过删选,后来让师姐帮我改了一下简历,重新投另一个部门,获得了面试机会.7月23日,中午HR打电话过来预约了下午4点半面试,说会在线写代码,让我准 ...
- codeforces1088D_Ehab and another another xor problem交互题
传送门 一道考验思维的交互题 大致思路就是从最高的二进制位向下询问 代入例子比如: 5 6 6 5 7 4 6 4 讨论一下 交互题的重点学会推理和归纳 #include <bits/stdc+ ...
- 佳木斯集训Day3
D3是我的巅峰 D3的出题人毒瘤!!!T3放了一道莫队,我们全体爆炸,到现在只有一个奆老A掉了T3 据说lkh被晓姐姐D了 T1是个26进制数,当时在考场上想了好久才想到(太次了)注意需要处理一下溢出 ...
- 【杂项】关于NOIP2018复赛若干巧合的声明
导言 参加NOIP2018时本人学龄只有两个月,却斩获了省一等奖,保送了重点中学,这看上去是个我创造的神话,然而,在我自己心中,我认为这只是个巧合(其实我认为运气也是实力的一部分),接下来,我将说明一 ...
- Zookeeeper环境搭建(二)
zk一般是有2n+1个节点组成的集群.在Zookeeper服务有两个角色,一个是leader,负责写服务和数据同步:剩下的是follower,提供读服务.(为什么是2n+1个节点请看paxos算法) ...
- jmh源码解析-整体架构
我理解的jmh运行架构图 生成字节码,字节码负责维护测试的状态和调用被测试的方法 默认在fork的进程中进行测试,可以配置多个fork进程,以减少误差 通过线程池,提交每个迭代的测试任务,任务执行后, ...
- RabbitMQ的基本介绍及与Spring整合
一,场景回顾 最近做电商购物项目,在分布式中搜索服务,商品详情服务都是独立的模块.那么有一个问题就是: 商品的原始数据保存在数据库中,增删改查都在数据库中完成. 搜索服务数据来源是索引库,如果数据 ...
- CodeForces 526D Om Nom and Necklace
洛谷题目页面传送门 & CodeForces题目页面传送门 给定字符串\(a\),求它的每一个前缀,是否能被表示成\(m+1\)个字符串\(A\)和\(m\)个字符串\(B\)交错相连的形式, ...
- 消息中间件——RabbitMQ(二)各大主流消息中间件综合对比介绍!
前言 消息队列已经逐渐成为企业IT系统内部通信的核心手段.它具有低耦合.可靠投递.广播.流量控制.最终一致性等一系列功能,成为异步RPC的主要手段之一.当今市面上有很多主流的消息中间件,如老牌的Act ...
- 面试java后端面经_2
1 自我介绍(介绍一下帅气的自己哦) 2 对象深浅复制(浅复制:对象内引用的对象不会复制,深复制会把引用对象复制.如何进行深浅复制,这块不懂的童鞋可以百度一下) 3 wait方法和sleep方法的区别 ...