理解IM消息“可靠性”和“一致性”问题,以及解决方案探讨

news2024/10/6 8:30:05

试想如果一个IM连发出的消息都不知道对方到底能不能收到、发出的聊天内容对方看到的到底是不是“胡言乱语”(严重乱序问题),这样的APP用户肯定不会让他在手机上过夜(肯定第一时间卸载了),因为最基本的聊天逻辑都无法实现,它已经失去了IM软件本身的意义。

不过,另一个方面来讲,IM系统是不标准的(虽然曾经XMPP这种协议试图解决这个问题,但事实证明那根本不现实),各家几乎都是自已的私有协议、不同的实现逻辑,这也决定了即使同一个技术问题,对于IM来说很难有固定的实现套路和标准的解决方案。

所以,对于本文来说,文中作者虽然提供了有关IM消息“可靠性”与“一致性”问题的解决方案,但方案到底合不合理、适不适合你,这就是仁者见仁、智者见智的事了。用人话说就是:本文内容仅供参考,具体的解决方案请务结合自已的系统构架和实现情况,多阅读几篇即时通讯网上有关这个技术话题的文章,取其精华,找到适合自已的技术方案和思路才是最明智的。

丛所周之,即时通讯聊天(IM)系统必需要解决消息可靠性及消息一致性问题(PS:如果具体IM系统是什么你都还没弄明白

这两个问题,通俗来说就是:

1)消息可靠性:简单来说就是不丢消息,会话一方发送消息,消息成功到达对方并正确显示;2)消息一致性:包括发送一方消息一致及会话双方消息一致,要求消息不重复,不乱序。

本文会从典型的IM消息发送逻辑开始,简单易懂地阐明消息可靠性、一致性问题的原理及可参考的技术解决方法,或许技术方案并不完美,但希望能为你的IM技术问题解决带来启发。

IM的消息发送一般的实现过程可以分为两个阶段:

1)发送方发送消息、服务端接收、返回消息 ACK 给发送方;2)服务端将消息推送到接收方。

判断消息发送是否成功主要依据第一阶段——即服务器是否接受到消息。

对于消息发送者来说,消息状态可以分为三类:

1)正在发送;2)发送成功;3)发送失败。

具体来说,这三类状态的具体意义是:

1)正在发送:发送方触发发送事件开始,到收到服务端返回消息对应 ACK 之前;2)发送成功:发送方收到消息对应 ACK 回复;3)发送失败:超过一定重发次数,未收到消息对应 ACK 回复。即时通讯聊天软件app开发可以加小蓝豆的v:weikeyun24咨询

4.1 重发机制

保证消息发送第一阶段(见本文“3、典型IM消息发送过程”一节)消息成功发送的方法是设立重发机制:

1)依据一定时长内是否收到消息对应 ACK,判断消息是否要重发;2)如果超过预设时长,就重新发送;3)当重发次数超过预设次数,就不再重发,判定该消息发送失败,修改消息发送状态。

PS:具体的完整方案级代码实现,可以参考MobileIMSDK 中有关QoS机制的代码实现。

4.2 会话记录检查

消息发送第二阶段(见本文“3、典型IM消息发送过程”一节)服务端推送消息到接收方,如果连接断开,会丢失消息。

所以要保证消息完整,就需要在建立连接后,根据上一条消息(已经 ACK)时间戳,获取会话记录,一次返回一段时间内所有消息(PS:中大型应用中,消息的拉取也不是个简单事情,

4.3 需要考虑的两个问题

消息重发、会话记录检查需要考虑两个问题:

1)消息是否会重复发送;2)消息顺序是否会被打乱。

举两个例子。

关于消息重发问题:

1)如果丢消息的点在消息达到服务端之前,服务端并没有收到消息,发送方重新发送丢失消息,服务端接收成功,不会产生两条相同消息;2)而如果服务端接收到消息,返回 ACK 丢失,这时再发送一次相同消息,就可能造成消息重复。

关于消息顺序问题:

1)如果发送方连发三条消息,第一、第三条成功被服务端接收,第二条丢了,那第三条消息是否会被记录?2)如果这时第二条消息达到服务端,其顺序是在第三条时间之前还是之后(服务端一般都会给记录打一个时间戳)?

5.2 使用向量时钟进行消息排序

对于消息排序问题:因为在聊天中,消息的顺序对于发送方的表述有重要的影响,消息不完整或顺序颠倒都可能造成语意不连贯,甚至曲解。所以需要保证发送方发送消息顺序,而会话双方消息排序需要考虑实际情况。

在一般的认知里:状态是正在发送的消息,应该还没有被对方看到,只有发送成功的消息,才会被对方看到。但在实现中,消息发送成功是以服务器接收消息并返回 ACK 成功为判断依据,而不是被对方接收到。

那么就会出现这样一个问题:如果一条消息状态是正在发送,此时收到一条消息,那么收到的消息是在正在发送的消息之前还是之后?

这是一个上下文关系,关键问题是:发送方是以哪条所见消息为依据发送消息的。

这里提供一种思路:借鉴分布式系统中的向量时钟算法(见《分布式系统中的向量时钟算法》)。

先简单描述向量时钟算法:

向量时钟算法用于在分布式系统中生成事件偏序关系,并纠正因果关系。一个系统包含 N 个节点,每个节点产生的消息体中包含该节点的逻辑时钟,整体系统的向量时钟由 N 维逻辑时钟组成,并在每个节点产生的消息体中传递。

简单来说,向量时钟算法的实现原理如下:

1)初始状态,向量值为 0;2)每次节点处理完节点事件,该节点时钟+1;3)每次节点发送消息,将包含自身时钟的系统向量时钟一起发送;4)每次节点收到消息,更新向量时钟,该节点时钟+1,其他节点对比每个节点本地保留的向量时钟值和消息体中向量时钟值,取最大值;5)节点同时收到多条消息,判断接收消息的向量时钟之间是否存在偏序关系。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/360632.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

python基础 | python基础语法

文章目录📚基础语法🐇输入和输出🥕print()输出🥕input()输入🐇 变量的命名🐇条件判断🥕单向判断🥕双向判断🥕多向判断🥕if嵌套🥕三元表达式&#…

漫画 | Python是一门烂语言?

这个电脑的主人是个程序员,他相继学习了C、Java、Python、Go, 但是似乎总是停留在Hello World的水平。 每天晚上,夜深人静的时候,这些Hello World程序都会热火朝天地聊天但是,这一天发生了可怕的事情随着各个Hello wor…

如何无报错运行代码YOLOv6,实现目标识别?

YOLOv6是由美团视觉团队开发的1.环境配置我们先把YOLOv6的代码clone下来git clone https://github.com/meituan/YOLOv6.git安装一些必要的包pip install pycocotools2.0作者要求pytorch的版本是1.8.0,我的环境是1.7.0,也是可以正常运行的pip install -r requirement…

RTOS之三裸机ADC转换与三轴加速计

参考:https://blog.csdn.net/qq_38427678/article/details/94607733各个pin口连接方式如下:// J1 J3 J4 J2// [ 1] [21] [40] [20]// [ 2] [22] [39] [19]// [ 3] [23] [38] [18]// [ 4] [24] [37] [17]// [ 5] [25] [36] [16]// [ 6] [26] [35] [15]// …

重温一下C#的时间类型,并简单写一个定时器功能

🎉🎉 时间是一个非常抽象的概念,本篇文章我们不深究目前电脑上的时候是如何保持全网同步。主要是讲讲在使用C#编程语言里的时间类型。最后使用定时任务简单写一个提醒功能,比如:每天10点准时打开一次csdn首页&#xff…

sk_buff结构体成员变量说明

一. 前言 Socket Buffer的数据包在穿越内核空间的TCP/IP协议栈过程中,数据内容不会被修改,只是数据包缓冲区中的协议头信息发生变化。大量操作都是围绕sk_buff结构体来进行的。 sk_buff结构的成员大致分为3类:结构管理域,常规数据…

cocos2d-x4.0 win10环境搭建

cocos2d-x默认只支持win32的版本,win64的我测试link不行 我搭建使用的环境 windows10vs2019py2.7cmake3 从GitHub上clone源码https://github.com/cocos2d/cocos2d-x coco2d-x默认带了submodule,有协同子模块,最好是一起下载,搞个…

国内知名插画培训机构有哪些

国内知名插画培训机构有哪些?给大家梳理了国内5家专业的插画师培训班,最新无大插画班排行榜,各有优势和特色! 一:国内知名插画培训机构排名 1、轻微课(五颗星) 主打课程有日系插画、游戏原画、古…

MYSQL 配置优化

max_connections 允许客户端并发连接的最大数量,默认值是151。 show status like %connections%; 设置参数值应大于Max_used_connections。如果使用连接池,可参考连接池的最大连接数和每个连接池的数量作为参考设置 innodb_buffe_pool_instances Inno…

【华为云-开发者专属集市】DevCloud+ECS、MySQL搭建WordPress

文章目录AppBazaar官网选择与购买项目项目概况操作过程购买DevCloud服务创建项目添加制品库应用部署购买ECS添加部署模板并执行任务故障排除安装及访问WordPress登录网站管理后台访问网站完善部署模板资源释放使用总结AppBazaar官网 首先,我们来到AppBazaar的官网&…

【Kubernetes】【十五】Service详解 Service介绍 类型 使用

第七章 Service详解 本章节主要介绍kubernetes的流量负载组件:Service和Ingress。 Service介绍 ​ 在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着…

数据库必知必会:TiDB(11)TiDB集群安装

数据库必知必会:TiDB(11)TiDB集群安装TiDB集群安装单机环境上安装集群下载并安装TiUP工具安装TiUP cluster组件创建拓扑文件配置SSH免密登录检查安装要求创建安装目录部署集群启动集群验证集群启动使用命令验证通过Dashboard查看通过Grafana查…

2023年1月冰箱品牌销量排行:销量环比增长26%,销售额36亿+

鲸参谋电商大数据2023年1月京东平台“冰箱”销售数据出炉! 根据鲸参谋平台电商数据显示,2023年1月份,在京东平台上,冰箱的销量将近130万件,环比增长26%,同比下滑8%;销售额达36亿,环比…

嵌入式开发:C++在深度嵌入式系统中的应用

深度嵌入式系统通常在C语言中实现。为什么会这样?这样的系统是否也能从C中获益?嵌入式开发人员在将广泛、高效的深度嵌入式代码库从C转换为C方面的实践经验的贡献。嵌入式和深度嵌入式系统通常用C而不是C实现。软件开发人员必须放弃C作为强类型系统、模板元编程(TMP)和面向对…

dubbo整合nacos进行远程调用

doubbo是什么? Apache Dubbo 最初在 2008 年由 Alibaba 捐献开源,很快成为了国内开源服务框架选型的事实标准框架 ,得到了各行各业的广泛应用。在 2017 年,Dubbo 正式捐献到 Apache 软件基金会并成为 Apache 顶级项目&#xff0c…

DJI 无人机 Onboard SDK ROS 功能包demo运行

DJI 无人机 Onboard SDK ROS 功能包demo运行demo功能准备测试环境运行 dji sdk 节点运行 demo 节点自动飞行任务航点自动飞行兴趣点环绕自动飞行飞行控制本地坐标位置控制搭建好 Onboard SDK ROS 的开发环境后,功能包自身具备一些写好的demo功能案例 dji sdk 的节点…

华为OD机试 - 猴子爬山 | 机试题算法思路 【2023】

使用说明 参加华为od机试,一定要注意不要完全背诵代码,需要理解之后模仿写出,通过率才会高。 华为 OD 清单查看地址:https://blog.csdn.net/hihell/category_12201821.html 华为OD详细说明:https://dream.blog.csdn.net/article/details/128980730 猴子爬山 | 华为OD机…

特征工程-定义+意义+安装scikit-learn+数据的特征抽取(字典、文本)

目录 数据中对特征的处理 特征工程定义 特征工程意义 安装scikit-learn 数据的特征抽取 字典特征抽取 DictVectorizer语法 文本特征抽取 CountVectorizer语法 TfidfVectorizer语法 数据中对特征的处理 pandas:一个数据读取非常方便以及基础的处理格式的工具 sklear…

Spring Boot + Vue3 前后端分离 实战 wiki 知识库系统<一>---Spring Boot项目搭建

前言: 接下来又得被迫开启新的一门课程的学习了,上半年末尾淘汰又即将拉开序幕【已经记不清经历过多少次考试了】,需要去学习其它领域的技术作为考试内容,我选了spring boot相关技术,所以。。总之作为男人&#xff0c…

Linux之网络流量监控工具ntopng YUM安装

一、ntopng简介 Ntop是一种监控网络流量工具,用ntop显示网络的使用情况比其他一些网络管理软件更加直观、详细。Ntop甚至可以列出每个节点计算机的网络带宽利用率。他是一个灵活的、功能齐全的,用来监控和解决局域网问题的工具;尤其当ntop与n…