news 2026/7/7 1:15:37

消息队列--消息顺序性保障

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
消息队列--消息顺序性保障

目录

参考美团技术团队博客

项目中实现思路


参考美团技术团队博客

两种通用的解决方案: 1. 版本号。 2. 状态机。

版本号

举个简单的例子,一个产品的状态有上线/下线状态。如果消息1是下线,消息2是上线。不巧消息1判重失败,被投递了两次,且第二次发生在2之后,如果不做重复性判断,显然最终状态是错误的。 但是,如果每个消息自带一个版本号。上游发送的时候,标记消息1版本号是1,消息2版本号是2。如果再发送下线消息,则版本号标记为3。下游对于每次消息的处理,同时维护一个版本号。 每次只接受比当前版本号大的消息。初始版本为0,当消息1到达时,将版本号更新为1。消息2到来时,因为版本号>1.可以接收,同时更新版本号为2.当另一条下线消息到来时,如果版本号是3.则是真实的下线消息。如果是1,则是重复投递的消息。 如果业务方只关心消息重复不重复,那么问题就已经解决了。但很多时候另一个头疼的问题来了,就是消息顺序如果和想象的顺序不一致。比如应该的顺序是12,到来的顺序是21。则最后会发生状态错误。 参考TCP/IP协议,如果想让乱序的消息最后能够正确的被组织,那么就应该只接收比当前版本号大一的消息。并且在一个session周期内要一直保存各个消息的版本号。 如果到来的顺序是21,则先把2存起来,待1到来后,先处理1,再处理2,这样重复性和顺序性要求就都达到了。

。。。

基于版本号来处理重复和顺序消息听起来是个不错的主意,但凡事总有瑕疵。使用版本号的最大问题是:

  1. 对发送方必须要求消息带业务版本号。
  2. 下游必须存储消息的版本号,对于要严格保证顺序的。

https://tech.meituan.com/2016/07/01/mq-design.htmlhttps://tech.meituan.com/2016/07/01/mq-design.html其中参考主要思想:

参考TCP/IP协议,如果想让乱序的消息最后能够正确的被组织,那么就应该只接收比当前版本号大一的消息。并且在一个session周期内要一直保存各个消息的版本号。 如果到来的顺序是21,则先把2存起来,待1到来后,先处理1,再处理2,这样重复性和顺序性要求就都达到了。

项目中实现思路

消息的顺序性保障不靠中间件去实施,在消费者这一侧来实现消息的顺序性。

一个broker的topic=xxxx 是专门用来发顺序消息的

消费者这边,收到消息之后全部落库不处理,落库成功之后返回ack。利用mysql存消息

数据库这边,business_key + version有唯一索引。重复消息被唯一索引幂等掉。

假设发的时 2 1 3 1 4,数据库真实存储的是2 1 3 4。

消费者这边处理的逻辑(伪代码)

while(ture) { // 查询所有未处理的消息,按bussiness_key 和 version 升序排列 List<Message> messages = DB.query("SELECT * FROM messages WHERE processed = FALSE ORDER BY business_key, version ASC"); for(Message msg : messages) { String businessKey = msg.getBusinessKey(); int version = msg.getVersion(); // 检查是否有上一版本号未处理 boolean preVersionProcessed = DB.esists( "SELECT 1 FROM messages WHERE business_key = ? AND version = ? AND processed = TRUE", businessKey, version - 1 ); // 如果是version=1,直接处理;或者上一个版本已经处理了,也可以处理当前版本 if (version == 1 || preVersionProcessed) { processMessage(msg); // 标记消息已处理 DB.update("UPDATE message SET processed = TRUE WHERE id = ?", msg.getId()); } else { continue; } } sleep(5000); }

优化点:避免重复读取,可以使用分布式锁,或者加行级锁,FOR UPDATE。加上事务机制。

List<Message> messages = DB.query("SELECT * FROM messages WHERE processed = FALSE ORDER BY business_key, version ASC");
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 6:34:11

2025最新!8个AI论文平台测评:继续教育写论文不再难

2025最新&#xff01;8个AI论文平台测评&#xff1a;继续教育写论文不再难 2025年AI论文平台测评&#xff1a;助力继续教育高效写作 随着人工智能技术的不断进步&#xff0c;越来越多的学术工作者开始借助AI工具提升论文写作效率。对于继续教育群体而言&#xff0c;时间紧张、专…

作者头像 李华
网站建设 2026/7/3 11:47:33

DNS劫持全解析:原理、危害与防御实战指南

前言 DNS英文全称Domain Name System&#xff0c;中文意思是域名系统&#xff0c;因此DNS劫持又被称为域名劫持&#xff0c;属于网络攻击的一种&#xff0c;其危害性也是不容忽视的。那么什么是DNS劫持?怎么防止DNS劫持攻击?具体请看下文。 什么是DNS劫持? DNS劫持又叫做域名…

作者头像 李华
网站建设 2026/7/3 11:51:31

CentOS Linux 内核参数优化实战指南

CentOS Linux 内核参数优化实战指南 在企业级服务器部署中&#xff0c;尤其是 Web 服务器、数据库服务器、中间件节点或高并发应用环境中&#xff0c;仅安装操作系统远远不够。合理的内核参数调优&#xff0c;是提升系统性能、增强安全性和保障高可用性的关键一步。 本文以 Cen…

作者头像 李华
网站建设 2026/7/4 13:53:45

智能升级新范式:Deepoc开发板如何重新定义扫地机器人的进化路径

当硬件迭代遭遇瓶颈&#xff0c;外接式智能模组正在成为家电进化的新引擎在家电智能化进入深水区的今天&#xff0c;扫地机器人行业面临着一个共性难题&#xff1a;如何让存量设备享受最新AI技术红利&#xff1f;传统的硬件升级路径不仅成本高昂&#xff0c;还造成资源浪费。De…

作者头像 李华
网站建设 2026/7/2 1:20:18

学长亲荐8个AI论文工具,研究生搞定开题报告+格式规范!

学长亲荐8个AI论文工具&#xff0c;研究生搞定开题报告格式规范&#xff01; AI 工具&#xff0c;正在重塑论文写作的未来 在研究生阶段&#xff0c;论文写作不仅是学术能力的体现&#xff0c;更是时间与精力的双重挑战。随着 AIGC 技术的不断发展&#xff0c;越来越多的 AI 工…

作者头像 李华