springboot rabbitmq如何保证消息顺序消费

很多时候,消息的消费是不用保证顺序的,比如借助mq实现订单超时的处理。但有些时候,业务中可能会存在多个消息需要顺序处理的情况,比如生成订单和扣减库存消息,那肯定是先执行生成订单的操作,再执行扣减库存的操作。

那么这种情况下,是如何保证消息顺序消费的呢?

首先,为了效率,我们可以设置多个队列都来处理顺序执行的消息。另外,我们需要保证每组顺序消费的消息发到同一个队列中,给这些消息设置一个统一的全局id即可。

其次,保证消息的顺序消费。就像上面所说,一个队列对应一个消费者即可,但是在项目的集群部署下,这又该怎么处理呢?针对这种情况,我们可以设置队列的“单活模式”。

x-single-active-consumer:单活模式,表示是否最多只允许一个消费者消费,如果有多个消费者同时绑定,则只会激活第一个,除非第一个消费者被取消或者死亡,才会自动转到下一个消费者。

 

 

要保证RabbitMQ消息的顺序消费,你需要做两件事:

  1. 确保消息进入相同的队列

  2. 对于队列,使用一个消费者,或者多个消费者,但要保证它们是排他的(exclusive),这意味着在任何时候只有一个消费者能够处理消息。

 以下是一个简单的例子:

@Configuration
public class RabbitConfig {
 
    // 创建队列,设置为排他的,此时队列的名称为routingKey
    @Bean
    Queue orderQueue() {
        return QueueBuilder.durable("routingKey")
                .exclusive()
                .build();
    }
 
    // 绑定交换机和队列,同时指定routingKey
    @Bean
    Binding bindingOrder(Queue orderQueue, FanoutExchange exchange) {
        return BindingBuilder.bind(orderQueue).to(exchange).with("routingKey");
    }
}
 
@Component
public class OrderConsumer {
 
    // 使用@RabbitListener注解指定队列名称,并保证这是Spring容器中唯一的消费者实例
    @RabbitListener(queues = "routingKey", concurrency = "1")
    public void handleOrder(String orderMessage) {
        // 处理消息的逻辑
    }
}

在这个配置中,所有带有routingKey的消息都会进入同一个排他队列。通过@RabbitListener注解的concurrency属性设置为1,确保了只有一个消费者来处理这个队列中的消息,从而保证了消息的顺序性。

请注意,如果你的应用中有多个消费者实例,确保它们都使用相同的队列名称,并且设置为排他。如果不是单实例部署,可能需要额外的同步机制来保证消息的顺序性。

 

稍微总结下:

  1. 消息发送,自己确保是有序的;集群化部署的话,可以通过分布式锁确保消息有序。
  2. 消息到达队列之后,默认就是有序的。
  3. 消息消费,一个队列对应一个消费者,并且一个消费者一个 channel,不能并发消费,就可以确保消息有序。

 

参考链接:

https://www.cnblogs.com/qian-fen/p/17613389.html

posted @ 2024-06-12 18:19  RuiB_WanAn  阅读(34)  评论(0编辑  收藏  举报