IM即时通讯开发实时消息的“时序性”与“一致性”

news2024/11/16 3:38:40

我们都知道,一个典型的分布式系统中,很多业务场景都需要考虑消息投递的时序,例如:

IM中单聊消息投递:保证发送方发送顺序与接收方展现顺序一致;IM中群聊消息投递:保证所有接收方展现顺序一致;电商充值支付消息:保证同一个用户发起的请求在服务端执行序列一致。

实时消息时序和一致性是分布式系统架构设计中非常难的问题(尤其IM应用这种以消息为中心的应用形态),困难在哪?有什么常见优化实践?这就是本文要讨论的内容。

凭什么说保证即时消息的时序、一致性很困难?

为什么分布式环境下,即时消息的时序难以保证,这边简要分析了几点原因:

1时钟不一致

分布式环境下,有多个客户端、有web集群、service集群、db集群,他们都分布在不同的机器上,机器之间都是使用的本地时钟,而没有一个所谓的“全局时钟”,所以不能用“本地时间”来完全决定消息的时序。

2多客户端(发送方)

多服务器不能用“本地时间”进行比较,假设只有一个接收方,能否用接收方本地时间表示时序呢?遗憾的是,由于多个客户端的存在,即使是一台服务器的本地时间,也无法表示“绝对时序”。

如上图,绝对时序上,APP1先发出msg1,APP2后发出msg2,都发往服务器web1,网络传输是不能保证msg1一定先于msg2到达的,所以即使以一台服务器web1的时间为准,也不能精准描述msg1与msg2的绝对时序。

3服务集群(多接收方)

多发送方不能保证时序,假设只有一个发送方,能否用发送方的本地时间表示时序呢?遗憾的是,由于多个接收方的存在,无法用发送方的本地时间,表示“绝对时序”。

如上图,绝对时序上,web1先发出msg1,后发出msg2,由于网络传输及多接收方的存在,无法保证msg1先被接收到先被处理,故也无法保证msg1与msg2的处理时序。

4网络传输与多线程

多发送方与多接收方都难以保证绝对时序,假设只有单一的发送方与单一的接收方,能否保证消息的绝对时序呢?结论是悲观的,由于网络传输与多线程的存在,仍然不行。

如上图,web1先发出msg1,后发出msg2,即使msg1先到达(网络传输其实还不能保证msg1先到达),由于多线程的存在,也不能保证msg1先被处理完。

5怎么保证绝对时序

通过上面的分析,假设只有一个发送方,一个接收方,上下游连接只有一条连接池,通过阻塞的方式通讯,难道不能保证先发出的消息msg1先处理么?

答案是:可以,但吞吐量会非常低,而且单发送方单接收方单连接池的假设不太成立,高并发高可用的架构不会允许这样的设计出现。即时通讯聊天软件app开发可以加小蓝豆的v:weikeyun24咨询

生产环境下的优化方法总结

1以客户端或者服务端的时序为准

多客户端、多服务端导致“时序”的标准难以界定,需要一个标尺来衡量时序的先后顺序。

不过,我们可以根据业务场景,以客户端或者服务端的时间为准,例如:

邮件展示顺序:其实是以客户端发送时间为准的,潜台词是,发送方只要将邮件协议里的时间调整为1970年或者2970年,就可以在接收方收到邮件后一直“置顶”或者“置底”;秒杀活动时间判断:肯定得以服务器的时间为准,不可能让客户端修改本地时间,就能够提前秒杀。

2服务端能够生成单调递增的id

这个是毋庸置疑的,不展开讨论,例如利用单点写db的seq/auto_inc_id肯定能生成单调递增的id,只是说性能及扩展性会成为潜在瓶颈。对于严格时序的业务场景,可以利用服务器的单调递增id来保证时序。

3大部分业务能接受误差不大的趋势递增id

消息发送、帖子发布时间、甚至秒杀时间都没有这么精准时序的要求:

同1s内发布的聊天消息时序乱了;同1s内发布的帖子排序不对;用1s内发起的秒杀,由于服务器多台之间时间有误差,落到A服务器的秒杀成功了,落到B服务器的秒杀还没开始,业务上也是可以接受的(用户感知不到)。

所以,大部分业务,长时间趋势递增的时序就能够满足业务需求,非常短时间的时序误差一定程度上能够接受。关于绝对递增id,趋势递增id的生成架构,详见文章《细聊分布式ID生成方法》,此处不展开。

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

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

相关文章

如何审计一个智能合约

智能合约审计用于整个 DeFi 生态系统,通过对协议代码的深入审查,可以帮助解决识别错误、低效代码以及这些问题。智能合约具有不可篡改的特点,这使得审计成为任何区块链项目安全流程的关键部分。 代码审计对任何应用程序都很重要,…

【ES】Elasticsearch核心基础概念:文档与索引

es的核心概念主要是:index(索引)、Document(文档)、Clusters(集群)、Node(节点)与实例,下面我们先来了解一下Document与Index。 RESTful APIs 在讲解Document与Index概念之前,我们先来了解一下RESTful APIs,因为下面讲解Documen…

Antd Form校验没有效果的问题

问题是这样的: 环境: antd4.x 现象: 如上页面 出现页面后直接点击按钮触发校验,不会有校验提示,页面没有任何反应假如只有其中任何一个,校验正常 比如,没有“模型编码”,只有“模…

变分推断 (Variational Inference) 解析

前言 如果你对这篇文章可感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。 变分推断 在贝叶斯方法中,针对含有隐变量的学习和推理,通常有两类方式,其一是马尔可…

Python爬虫:如何自动化下载网站图片

目录 Requests 访问页面 XPath 定位 JSON 对象 如何使用 XPath 自动下载百度图片 Selenium 库模拟浏览器 Requests 访问页面 Requests 是 Python HTTP 的客户端库,编写爬虫的时候都会用到,编写起来也很简单。它有两种访问方式:Get 和 P…

王道操作系统课代表 - 考研计算机 第五章 输入输出管理 究极精华总结笔记

本篇博客是考研期间学习王道课程 传送门 的笔记,以及一整年里对 操作系统 知识点的理解的总结。希望对新一届的计算机考研人提供帮助!!! 关于对 “输入输出管理” 章节知识点总结的十分全面,涵括了《操作系统》课程里的…

基于.NET 7 + iView 的前后端分离的通用后台管理系统开源框架

更多开源项目请查看:一个专注推荐.Net开源项目的榜单 今天给大家推荐一套前后端分离通用后台管理系统开源框架。 项目简介 这是基于.Net 7 Vue.js开发的、前后端分离框架,前端UI框架采用iView,该项目只有基础功能模块,不包含具…

VMware虚拟机安装centos(超详细图文教程)

1、centos下载 Ubuntu下载地址:点这里 下载不成功的也可关注公众号获取:待更新 2、打开VMware VMware安装过程:待更新 2.1 创建新的虚拟机 2.2 一般情况都会选择典型(如果这里有需要选择自定义的一般也不会看教程了&#xff…

【Spark分布式内存计算框架——Spark Streaming】10. 应用案例:百度搜索风云榜(中)实时数据ETL存储

5.3 实时数据ETL存储 实时从Kafka Topic消费数据,提取ip地址字段,调用【ip2Region】库解析为省份和城市,存储到HDFS文件中,设置批处理时间间隔BatchInterval为10秒,完整代码如下: package cn.itcast.spar…

华为机试题:HJ94 记票统计(python)

文章目录(1)题目描述(2)Python3实现(3)知识点详解1、input():获取控制台(任意形式)的输入。输出均为字符串类型。1.1、input() 与 list(input()) 的区别、及其相互转换方…

linux和windows中安装emqx消息服务器

大家好,我是雄雄,欢迎关注微信公众号雄雄的小课堂 现在是:2023年3月1日21:53:55 前言 最近几天看了下mqtt,通过不断的搜索资料,也将mqtt集成到项目中,跑了个demo运行,和预想中的差不多&#x…

Altair 宣布将于3月举办 Future.Industry 2023 全球虚拟大会

Altair(纳斯达克股票代码:ALTR)近日宣布将于 2023 年 3 月 8 - 9 日 举办年度全球虚拟大会 Future.Industry 2023。旨在探索影响全球未来的新趋势,并深入探讨仿真、高性能计算 (HPC)、人工智能(AI)和数据分…

使用jenkins+nginx自动化部署前后端项目并打包备份

前言:因为之前使用docker拉取的jenkins无法检测到本地服务器安装的jdk和maven,所以我在本地服务器直接拉取了jenkins,使用8090端口与docker拉取的jenkins进行对比,可以检测到本地服务器安装的jdk和maven,前端和后端分开…

ETHDenver 2023

ETHDenver是全球最大、持续时间最长的以太坊活动之一,今年的活动定于2月24日至3月5日在美国科罗拉多州丹佛市盛大举行。这次活动将面向以太坊和其他区块链协议爱好者、设计者和开发人员。Moonbeam作为ETHDenver 2023的Meta赞助商,将在本次活动中展示令人…

如何使用crAPI学习保护API的安全

关于crAPI crAPI是一个针对API安全的学习和研究平台,在该工具的帮助下,广大研究人员可以轻松学习和了解排名前十的关键API安全风险。因此,crAPI在设计上故意遗留了大量安全漏洞,我们可以通过 crAPI学习和研究API安全。 crAPI采用…

如何把照片的底色修改为想要的颜色

如何给照片更换底色?其实有可以一键给照片更换底色的 APP ,但是几乎都要收费。如果想要免费的给照片更换底色的话,分享两种简单便捷的方法给你。掌握了这项技能,以后就不用店花钱处理啦!1、免费!线上快速 给…

【SpringBoot教程】SpringBoot入门

SpringBoot介绍 SpringBoot简介 在您第1次接触和学习Spring框架的时候,是否因为其繁杂的配置而退却了?在你第n次使用Spring框架的时候,是否觉得一堆反复黏贴的配置有一些厌烦?那么您就不妨来试试使用Spring Boot来让你更易上手&…

Rancher Prime 为平台工程提供面向 K8s 的弹性能力

作者简介 张应罗,SUSE 资深架构师,拥有 16 年架构咨询工作经验,专注于 SUSE Enterprise Container Management 相关的产品落地方案及咨询方案设计。 平台工程 “DevOps 已死,平台工程才是未来!” 去年,知名软件工程师…

原来JS可以这么实现继承

当我们在编写代码的时候,有一些对象内部会有一些方法(函数),如果将这些函数在构造函数内部声明会导致内存的浪费,因为实例化构造函数得到不同的实例对象,其内部都有同一个方法,但是占据了不同的…

【unity】开发rts 4 放置建筑进地图;创建单位;单位移动;单位生产者

一 放置建筑进地图 1 GameManage,slot faction阵营插槽, 新建筑拖进secne,便于管理,在实例栏将建筑放在factions下 inital faction entitys,(也可带上cam look at) 添加新建筑上 此时测试&a…