Alibaba Spring Cloud 二十 RocketMQ顺序消息

在分布式消息系统中,通常默认情况下无法保证消息的严格顺序,因为消息会被拆分到多个分区(Queue)进行并行存储和消费。但在某些业务场景下(如订单流程、支付流水处理等),我们需要保证针对同一业务实体(例如同一个订单 ID)的所有消息按照发送顺序被消费。

RocketMQ 通过**顺序消息(Ordered Message)**特性为我们提供了有序消费的能力。下面将从概念、原理、使用示例和常见问题几个方面进行说明。


1. 顺序消息的概念

  • 全局顺序:所有发送到某个 Topic 的消息都按照其发送顺序被消费。这要求 Topic 在物理上只有一个 Queue 或只用一个消费者线程来处理消息,一般不适用于高并发场景。
  • 分区顺序(分区有序):同一分区(Queue)内的消息按照先后顺序被消费,不同分区之间互不影响。在业务层面,如果能够将相同业务实体(如相同订单 ID)的消息路由到同一分区,即可保证该实体维度下的顺序性。

实践中,大多数场景采用分区顺序,因为它可以在保证业务实体局部顺序的同时,仍然保留一定的并行消费能力。


2. RocketMQ 顺序消息的原理

  1. 消息在 Broker 上的存储
    RocketMQ 默认将同一 Topic 的消息分散到多个 Queue 上。若要实现某些消息的顺序消费,需要对相同“业务键”或“分组键”进行一致的分区路由,让它们全部写入相同的 Queue。

  2. 消费端的有序消费
    在消费时,RocketMQ 提供了 “顺序消费 (Orderly)” 的拉取方式(ConsumeMessageOrderlyService),会串行地对每个 Queue 逐一加锁并顺序拉取、处理消息,避免并发消费同一 Queue 上的消息。

    • 只有当 Consumer 成功处理了当前 Queue 上的消息,并提交消费进度,才会继续拉取下一批消息。
    • 因此,一个分区(Queue)对应一个消费线程,从而在该 Queue 上保证消息的处理顺序。

3. 顺序消息的使用示例

3.1 Producer 侧(发送有序消息)

在 RocketMQ 的 Java Client 中,可以通过在 send() 方法中指定消息队列选择器MessageQueueSelector)的方式,将带有相同业务键的消息发送到同一个 Queue 上。

DefaultMQProducer producer = new DefaultMQProducer("orderly_producer_group");
producer.setNamesrvAddr("127.0.0.1:9876");
producer.start();

String topic = "OrderTopic";

// 假设有多个订单 ID,这里用相同订单ID来演示
int orderId = 123456;

try {
   
   
    for (int i = 0; i < 5; i++) {
   
   
        String body = "Order Step " 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十方来财

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值