当前位置: 首页 > news >正文

RocketMQ中的顺序消息和乱序消息详解

内容编辑中…

1.背景

顺序消息是消息队列 RocketMQ 提供的一种高级消息类型。

对于一个指定的Topic,消息严格按照先进先出(FIFO)的原则进行消息发布和消费。

即先发送的消息先消费,后发送的消息后消费。

顺序消息在发送、存储和投递的处理过程中,强调多条消息间的先后顺序关系。RocketMQ 顺序消息的顺序关系通过消息组(MessageGroup)判定和识别,发送顺序消息时需要为每条消息设置归属的消息组,相同消息组的多条消息之间遵循先进先出的顺序关系,不同消息组、无消息组的消息之间不涉及顺序性。

2.顺序消息的特性

1、消息消费失败或消费超时,会触发服务端重试逻辑,重试消息属于新的消息,原消息的生命周期已结束;

2、顺序消息消费失败进行消费重试时,为保障消息的顺序性,后续消息不可被消费,必须等待前面的消息消费完成后才能被处理。

3、顺序消息仅支持使用MessageType为FIFO的主题,即顺序消息只能发送至类型为顺序消息的主题中,发送的消息的类型必须和主题的类型一致。

3.顺序消息 VS 普通消息

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

顺序消息普通消息
原子性消息之间存在偏序关系消息之间没有关联关系
顺序性严格有序大致有序
扩展性具备一定的可拓展性可拓展性强
吞吐受到消息队列数量限制,容易导致消息积压
并发单元同一MessageGroup的消息单条消息
编码要求相对较高

4.应用场景

RocketMQ 的顺序消费(也称为有序消息或顺序消息)在某些业务场景中是至关重要的,特别是在那些对消息处理顺序有严格要求的情况下。以下是几种会用到顺序消费的典型场景:

金融交易:例如,在处理用户的账户余额更新时,所有与该用户账户相关的操作必须按照发生的顺序进行处理。如果先处理了取款消息而后处理存款消息,可能会导致用户的账户余额出现错误。
订单处理系统:在一个电商环境中,从下单、支付到发货等步骤都需要保证按顺序执行。比如,不能在订单未创建之前就进行支付确认,也不能在未支付之前就开始发货。
工作流管理:当业务逻辑涉及多个步骤并且这些步骤之间存在依赖关系时,确保每个任务按照正确的顺序被执行是非常重要的。例如,文档审批流程可能需要依次通过不同级别的审核人员。
实时数据分析和日志处理:对于一些需要根据事件发生的时间序列来进行分析的应用来说,保持数据摄入的顺序性可以简化下游处理逻辑并提高准确性。
库存管理系统:产品入库、出库等操作也需要遵循一定的顺序,以确保库存数量的准确性。
为了实现顺序消费,RocketMQ 提供了两种类型的顺序消息:全局顺序和分区顺序

5.全局顺序和分区顺序

5.1 全局有序

可以为Topic设置一个消息队列,使用一个生产者单线程发送数据,消费者端也使用单线程进行消费。

从而保证消息的全局有序,但是这种方式效率低,一般不使用。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5.2 分区有序

在同一 Topic 下的不同分区(Queue)之间不保证顺序,但在同一分区内的消息则保持严格的顺序。

假设一个Topic分配了两个消息队列,生产者在发送消息的时候,可以对消息设置一个路由ID。

比如想保证一个订单的相关消息有序,那么就使用订单ID当做路由ID。
在发送消息的时候,通过订单ID对消息队列的个数取余,根据取余结果选择消息队列。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
这样同一个订单的数据就可以保证发送到一个消息队列中。
消费者端使用MessageListenerOrderly处理有序消息。

这就是RocketMQ的局部有序,保证消息在某个消息队列中有序
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
在实际应用中,通常会选择分区顺序而非全局顺序,因为后者可能导致性能瓶颈(所有的消息都要经过同一个队列),而前者可以在一定程度上平衡顺序性和吞吐量。

为了确保顺序消费的有效性,RocketMQ 使用了特定的消息发送策略(如基于哈希值选择相同的 MessageQueue)以及特殊的消费者监听器(MessageListenerOrderly),它会在消费端加锁以确保同一队列中的消息被单线程顺序处理。

此外,顺序消息不适合使用广播模式,并且建议不要异步发送这类消息,以免破坏其顺序性。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
下面用订单进行分区有序的示例。

5.3 分区有序示例

一个订单的顺序流程是:创建、付款、推送、完成。订单号相同的消息会被先后发送到同一个队列中,消费时,同一个 Orderld 获取到的肯定是同一个队列。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

6.顺序消费的条件

需要注意的是 RocketMQ 消息的顺序性分为两部分,生产顺序性和消费顺序性。只有同时满足了生产顺序性和消费顺序性才能达到上述的FIFO效果。

6.1 生产顺序性

在分布式环境下,保证消息的全局顺序性是十分困难的,例如两个 RocketMQ Producer A 与 Producer B,它们在没有沟通的情况下各自向 RocketMQ 服务端发送消息 a 和消息 b,由于分布式系统的限制,我们无法保证 a 和 b 的顺序。

因此业界消息系统通常保证的是分区的顺序性,即保证带有同一属性的消息的顺序,我们将该属性称之为 MessageGroup。如图所示,ProducerA 发送了 MessageGroup 属性为 A 的两条消息 A1,A2 和 MessageGroup 属性为 B 的 B1,B2,而 ProducerB 发送了 MessageGroup 属性为 C 的两条属性 C1,C2。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
同时,对于同一 MessageGroup,为了保证其发送顺序的先后性,比较简单的做法是构造一个单线程的场景,即不同的 MessageGroup 由不同的 Producer 负责,并且对于每一个 Producer 而言,顺序消息是同步发送的。同步发送的好处是显而易见的,在客户端得到上一条消息的发送结果后再发送下一条,即能准确保证发送顺序,若使用异步发送或多线程则很难保证这一点。
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
我们简单总结一下顺序发送
RocketMQ 通过生产者和服务端的协议保障单个生产者串行地发送消息,并按序存储和持久化。如需保证消息生产的顺序性,则必须满足以下条件:

  • 单一生产者: 消息生产的顺序性仅支持单一生产者,不同生产者分布在不同的系统&#x
http://www.lryc.cn/news/504014.html

相关文章:

  • Unity UGUI图片循环列表插件
  • Kafka系列教程 - Kafka 生产者 -2
  • AI Chat API 对接说明
  • Thread线程基础使用
  • 【Linux】结构化命令
  • ElasticSearch01-概述
  • docker xxxx is using its referenced image ea06665f255d
  • Vue 2 中 v-text 和 v-html 指令的使用详解
  • 高级Python游戏开发:创建一款多人对战坦克大战
  • 数据结构_拓扑排序
  • Edge SCDN 边缘安全加速有什么用?
  • 被狗咬住怎么让它松口?
  • MySQL迁移SQLite 借助PYTHON脚本
  • Python什么是动态调用方法?What is Dynamic Method Invocation? (中英双语)
  • Cesium中实现仿ArcGIS三维的动态图层加载方式
  • 数据冒险、控制冒险、结构冒险
  • TCA9555芯片手册解读(6)
  • NodeJs-fs模块
  • Transformer: Attention Is All You Need (2017) 翻译
  • 【记录】Django解决与VUE跨域问题
  • Java 常见Exception异常解决方法
  • 东方通 TongWebV7 Docker 部署与 Spring Boot 集成指南
  • TIM输入捕获---STM
  • 【笔记】架构上篇Day6 法则四:为什么要顺应技术的生命周期?
  • MSF(Metasploit Framework)
  • Python中的OpenCV详解
  • IMX6ULL开发板学习嵌入式技术过程中为了测试本地网络是否正常而常用的Ping命令
  • Blue Ocean 在Jenkins上创建Pipeline使用详解
  • 2024 年最新前端ES-Module模块化、webpack打包工具详细教程(更新中)
  • photoshop的2个形状-箭头