《即时消息技术剖析与实战》学习笔记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 年. ...
随机推荐
- 原生js实现图片懒加载+加入节流
这两天在学习图片的懒加载实现,看了很多大佬的博客,终于有了点成果.现在用了其中一位大佬的文章中的代码实现了图片懒加载并且在其基础上加入了节流函数. 原理就不多讲了,有需要的可以去大佬的文章看看.大佬文 ...
- [Spring cloud 一步步实现广告系统] 15. 使用开源组件监听Binlog 实现增量索引准备
MySQL Binlog简介 什么是binlog? 一个二进制日志,用来记录对数据发生或潜在发生更改的SQL语句,并以而进行的形式保存在磁盘中. binlog 的作用? 最主要有3个用途: 数据复制( ...
- web面试
什么是面向对象? 程序中的事物都是用对象结构来描述的,所有的程序都是用面向对象的思想,管理数据和功能的. 面向对象三大特点:封装 继承 多态 什么是封装? 创建一个对象结构,用来保存一个事物的属性和方 ...
- 第三方登录之QQ
public class MainActivity extends AppCompatActivity { private Button btn; private TextView tv; priva ...
- python自动化运维技术读书笔记
import psutilprint(psutil.cpu_times(percpu=True)) #使用cpu_times方法获取CPU完整信息需要显示所有逻辑CPU信息 import psutil ...
- 大陆争霸[SDOI2010]带限制最短路
只要你有无限个自爆机器人,你就能为所欲为 斯普林·布拉泽 [题目描述] 略 一句话题意: 杰森国有 \(N\) 个城市,由 \(M\) 条单向道 路连接.杰森国的首都是城市 \(N\).你只需摧毁杰森 ...
- LoRaWAN调试踩坑心得(二)
先说两句 抱歉,由于工作原因和个人原因,中间停更了这么久.接下来,本人会继续往下更,内容包括但不仅限于LoRa.文章还是会按照个人的习惯,坚持原创,一是作为自己的笔记,二是和广大工程师分享交流. Lo ...
- SpringBoot进阶教程(六十)intellij idea project下建多个module搭建架构(上)
在 IntelliJ IDEA 中,没有类似于 Eclipse 工作空间(Workspace)的概念,而是提出了Project和Module这两个概念.多module有一个父maven工程,多个子工程 ...
- JD面试 || 移除教室人数
在昨天参加了东哥的笔试,选择题做的还算可以,但是还有道编程题和关于jdk8的Stream特性难住了.鉴于此用博客总结一下这道编程题,并结合Stream特性来简化代码,熟悉Api. 题目描述 某校在积极 ...
- freemarker导出复杂样式的Excel
freemarker导出复杂样式的Excel 代码地址: gitee https://gitee.com/suveng/demo/tree/master/chapter.002 代码存放于demo下面 ...