【消息队列】——如何实现消息保序

目录

    • 一、哪些场景需要消息保序?
    • 二、如何实现消息保序?
    • 三、保序消息的常见问题和应对策略
      • 3.1、重复消息
      • 3.2、节点故障
      • 3.3、分区扩容
    • 四、小结

本文来源:极客时间vip课程笔记

一、哪些场景需要消息保序?

  • 消息保序问题指的是,在通过消息中间件传递消息过程中,我们希望消费者收到消息的顺序,和发送者发送消息的顺序保持一致。或者说,消息中间件在传递消息时,不要改变消息之间的顺序。
  • 过在工程实践中,我们面临的保序问题不一定只是局限在消息保序这一个环节,更常见的场景是,事件经过包含消息队列等多个环节的处理和传递后,在某个服务内能够按照事件发生的顺序来逐个处理这些事件,不发生乱序。比如:
    (1)、在证券、股票交易撮合场景中,对于出价相同的交易单,需要坚持按照先出价先交易的原则,下游处理订单的系统需要严格按照出价顺序来处理订单。
    (2)、在数据库变更增量同步场景中,上游源端数据库按需执行增删改操作,将 BINLOG 作为消息,通过消息队列传输到下游系统,下游系统按顺序还原消息数据,实现状态数据有序更新。
    (3)、在电商系统中,订单创建、支付、退款、物流等消息需要按照顺序处理,才能保证订单状态的正确更新。

二、如何实现消息保序?

  • 有些消息队列其设计就是基于队列来实现的,比如 RabbitMQ。

  • 我们知道队列的特性就是先进先出,天然就是有序的,使用这种“基于队列来实现的消息队列”传递消息,自然就可以实现消息保序。

  • 但是为了实现高吞吐,更多的消息队列在设计上采用的是多分区或多队列的实现,比如 Kafka 或 RocketMQ 。这些消息队列在处理消息时,会将消息按照一定的策略分发到多个分区上并行处理,也就无法保证消息的有序性了。

    如果我们希望在多分区的消息队列上实现消息保序,可以将分区数量配置为 1,这样就可以实现和单队列消息中间件一样的保序效果了。

  • 此外,为了保证在消费者端消息的有序性,消费者也只能单实例单线程来消费消息,才能保证全流程消息是严格有序的。

  • 以上就是全局消息保序的实现方法,这种方法的实现思路其实就是全局串行处理。我们知道,串行处理有一个很大的弊端,那就是消息吞吐量有限,也没法通过水平扩展来提升消息吞吐量。在规模比较大的场景下就显得力不从心了。

  • 我们会发现,大多数需要消息保序的场景并不需要消息“全局有序”。多数场景下,我们只需要保证有业务关系的消息之间的顺序就可以了,没有业务关系的消息之间的先后顺序,其实是无所谓的。

  • 只有数据库 BINLOG 同步这个场景,因为数据库事务的存在,我们没有办法把 BINLOG 归并到数据库表上,也就无法判断 BINLOG 消息的关联性,这种情况下必须实现全局保序,才能保证数据同步的正确性。

    将保序要求从全局放宽到局部,就可以充分利用多分区消息队列的并发能力来提升消息吞吐量了。

  • 实现的思路是这样的,既然我们只需要保证有关联的消息之间的顺序,那么只要把关联的消息都发送给同一个分区处理,而分区内天然就可以保证消息的处理顺序,这样就实现了消息局部保序。下面举个例子来说明。

  • 比如,我们用一个 4 分区的主题来处理订单消息。可以采用哈希算法将订单消息按照订单号的后两位均匀地分配到 4 个分区上。

  • 也就是,将订单尾号 00-24 的订单发给 0 号分区,25-49 尾号的订单分给 1 号分区,50-74 尾号的订单发给 2 号分区,剩余的发给 3 号分区。这样就可以保证同一个订单的消息总是分配相同的分区,也就实现了订单内消息保序。

  • 多数消息中间件都内置了相应的功能来帮助我们快速实现局部消息保序。

  • 以 Kafka 为例,Kafka 的 API 支持在发送消息的时候指定一个消息的 Key,并且内置了默认的哈希算法将 Key 映射到主题的分区上,保证具有相同 Key 的消息总是会被发送到同一分区,从而实现了消息局部保序。在上面例子中,可以直接使用订单号作为消息的 Key,示例代码如下:

    // 订单消息
    OrderMessage orderMessage = createOrderMessage(...);
    // 订单号,作为Key
    String orderId = orderMessage.getOrderId();

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

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

相关文章

Transformer模型详解

Transformer Transformer真是个细节满满的框架呢,大三读到根本不敢看,考研复试前看了看,以为懂了其实差得还远,两个多月前看了,还是一知半解,如今终于经过细细分析,算是知道了Transformer的基本…

火山引擎发布豆包大模型 1.6 与视频生成模型 Seedance 1.0 pro

6 月 11 日,在火山引擎 FORCE 原动力大会上,字节跳动旗下火山引擎正式发布豆包大模型 1.6、豆包・视频生成模型 Seedance 1.0 pro、豆包・语音播客模型,豆包・实时语音模型也在火山引擎全量上线,豆包大模型家族已成为拥有全模态、…

PH热榜 | 2025-06-12

1. Atlas 标语:几秒钟内了解定价情况 介绍:获取即插即用的定价页面,让你轻松赚钱,不再辛苦操劳。 产品网站: 立即访问 Product Hunt: View on Product Hunt 关键词:Atlas, 定价快速, 插件式…

ChatGPT革命升级!o3-pro模型重磅发布:开启AI推理新纪元

2025年6月10日,OpenAI以一场低调而震撼的发布,正式推出了新一代推理模型o3-pro,这标志着人工智能在复杂问题解决领域的重大突破。作为ChatGPT Pro和Team订阅用户的专属工具,o3-pro不仅重新定义了AI的可靠性标准,更以其…

NVIDIA Isaac GR00T N1.5 适用于 LeRobot SO-101 机械臂

系列文章目录 目录 系列文章目录 前言 一、简介 二、详细教程 2.1 数据集准备 2.1.1 创建或下载您的数据集 2.1.2 配置模态文件 2.2 模型微调 2.3 开环评估 2.4 部署 🎉 快乐编程!💻🛠️ 立即开始! 前言 一…

【编译工具】(自动化)自动化测试工具:如何让我的开发效率提升300%并保证代码质量?

目录 引言:自动化测试在现代开发中的关键作用 一、自动化测试金字塔:构建高效的测试策略 (1)测试金字塔模型 (2)各层级代表工具 二、前端自动化测试实战:Jest Cypress (1&…

R语言缓释制剂QBD解决方案之一

本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》缓释制剂包衣处方研究的R语言解决方案。 ER聚合物包衣处方优化研究 基于初步风险评估和初始可行性研究,进行带3个中心点的24-1分式析因DOE。药物的释放被识别为CQA。本研究的…

行为模式-命令模式

定义: 命令模式是一个高内聚的模式,其定义为:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成…

Ubuntu 24.04 上安装与 Docker 部署 Sentinel

Ubuntu 24.04 上安装与 Docker 部署 Sentinel 一、Sentinel 简介 Sentinel 是阿里巴巴开源的分布式系统流量控制组件,提供流量控制、熔断降级和系统负载保护等功能。它通过可视化控制台(Dashboard)实现实时监控和规则管理,是微服…

IP 地址查询在证券交易中的应用方式

网络安全保障与IP地址查询 证券交易平台存储着海量投资者的敏感信息以及巨额资金的交易数据,是网络攻击的重点目标。IP 地址查询在检测异常登录行为方面至关重要。例如,当一个账户短时间内先在国内某城市登录,随后又在境外 IP 地址发起交易操…

Flutter 常用组件详解:Text、Button、Image、ListView 和 GridView

Flutter 作为 Google 推出的跨平台 UI 框架,凭借其高效的渲染性能和丰富的组件库,已经成为移动应用开发的热门选择。本文将深入探讨 Flutter 中最常用的五个基础组件:Text、Button、Image、ListView 和 GridView,帮助开发者快速掌…

docker 单机部署redis集群(一)

docker 部署redis集群 1、创建redis网卡 docker network create redis --subnet 172.38.0.0/16查看网卡信息 docker network ls docker network inspect redis2、创建redis配置 #使用脚本创建6个redis配置for port in $(seq

MySQL 索引学习笔记

1.二叉树,红黑树,B 树,B树 二叉树:就是每个节点最多只能有两个子节点的树; 红黑树:就是自平衡二叉搜索树,红黑树通过一下五个规则构建: 1.节点只能是红色或黑色; 2.根…

Windows安装docker及使用

下载 https://www.docker.com/ 安装 启动 此时拉取镜像会报错 Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 配置引擎 添加以…

多参表达式Hive UDF

支持的操作符 :跳过,即无条件筛选:等于!:不等于range:区间内,range[n,m]表示 between n and mnrange:区间外,即not between andin:集合内,in(n,m,j,k)表示 in…

GO后端开发内存管理及参考答案

什么是 Go 的逃逸分析(Escape Analysis),为什么需要它? Go 的逃逸分析是一种编译时技术,用于确定变量的生命周期是否超出其创建的函数作用域。通过分析变量的使用方式,编译器能够判断变量是否需要在堆上分…

未来智能系统演进路线:从AGI到ASI的技术蓝图

引言:智能革命的下一个十年 在AI技术突破性发展的当下,我们正站在通用人工智能(AGI)向人工超级智能(ASI)跃迁的关键转折点。本文将系统解析未来3-10年的技术演进路径,通过模块化组件插件&#…

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明: 想象一下,你正在用eNSP搭建一个虚拟的网络世界,里面有虚拟的路由器、交换机、电脑(PC)等等。这些设备都在你的电脑里面“运行”,它们之间可以互相通信,就像一个封闭的小王国。 但是&#…

AI Agent 核心策略解析:Function Calling 与 ReAct 的设计哲学与应用实践

引言 在人工智能助手和自主Agent快速发展的今天,如何让AI系统不仅能够理解复杂指令,还能有效地执行任务并适应动态环境,成为技术演进的关键问题。本文将深入探讨两种核心的Agent设计策略:Function Calling(函数调用&a…

window下配置ssh免密登录服务器

window下配置ssh免密登录服务器 本地windows远程登录我的ssh服务器10.10.101.xx服务器,想要每次都免密登录这个服务器. 记录下教程,防止后期忘记,指导我实现这个过程。 教程 二、实践步骤:Windows 上配置 SSH 免密登录 2.1 确…