很多时候,消息的消费是不用保证顺序的,比如借助mq实现订单超时的处理。但有些时候,业务中可能会存在多个消息需要顺序处理的情况,比如生成订单和扣减库存消息,那肯定是先执行生成订单的操作,再执行扣减库存的操作。
那么这种情况下,是如何保证消息顺序消费的呢?
首先,为了效率,我们可以设置多个队列都来处理顺序执行的消息。另外,我们需要保证每组顺序消费的消息发到同一个队列中,给这些消息设置一个统一的全局id即可。
其次,保证消息的顺序消费。就像上面所说,一个队列对应一个消费者即可,但是在项目的集群部署下,这又该怎么处理呢?针对这种情况,我们可以设置队列的“单活模式”。
x-single-active-consumer:单活模式,表示是否最多只允许一个消费者消费,如果有多个消费者同时绑定,则只会激活第一个,除非第一个消费者被取消或者死亡,才会自动转到下一个消费者。
要保证RabbitMQ消息的顺序消费,你需要做两件事:
-
确保消息进入相同的队列。
-
对于队列,使用一个消费者,或者多个消费者,但要保证它们是排他的(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
,确保了只有一个消费者来处理这个队列中的消息,从而保证了消息的顺序性。
请注意,如果你的应用中有多个消费者实例,确保它们都使用相同的队列名称,并且设置为排他。如果不是单实例部署,可能需要额外的同步机制来保证消息的顺序性。
稍微总结下:
- 消息发送,自己确保是有序的;集群化部署的话,可以通过分布式锁确保消息有序。
- 消息到达队列之后,默认就是有序的。
- 消息消费,一个队列对应一个消费者,并且一个消费者一个 channel,不能并发消费,就可以确保消息有序。
参考链接:
https://www.cnblogs.com/qian-fen/p/17613389.html
标签:顺序,消费者,队列,routingKey,rabbitmq,保证,消息,springboot From: https://www.cnblogs.com/xiaojunbo/p/18244495