面试官:你能说说RabbitMQ是如何保证消息顺序消费的吗?

老任:如果我们想要保证消息是按照顺序进行发送的,发送到队列后,队列的消息应该是先进先出的,我们只需要一个队列配置一个消费者即可(窃喜中......)。

面试官:我们的项目一般都是集群部署的,一个队列就会有多个消费者,怎么实现一个队列中所有顺序消息只能有一个消费者消费呢?

老任:这个好办,项目不做集群部署不就行了。

面试官:回去等通知吧......

一. 场景介绍

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

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

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

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

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

二. 模拟代码实现

假设现在我们有两个队列处理顺序消息(消息1-1和1-2属于一组需要顺序消费的消息,消息2-1和2-2属于另一组需要顺序消费的消息),每个队列有两个消费者(模拟消费者集群)。

1.队列的配置类

2.生产者

3.消费者

为了模拟,我们可以创建四个消费者,每两个消费者监听一个队列。四个消费者的逻辑一样,只是类名和监听的队列名不一样。消费者1的代码实现如下:

消费者2的代码实现:

消费者3的代码实现:

消费者4的代码实现:

4.测试

发送4个消息模拟顺序消费的消息,id为1和3的发送到一个队列,id为2和4的发送到另一个队列。

输出结果:

从结果中可以看到,虽然一个队列配置了两个消费者,但是每对顺序消息只有一个消费者顺序消费。

另外,我们还可以看到队列中“SAC”,表示启用了单活模式,这样我们就实现了这个需求,现在你学会了吗?

文章推荐:

软件测试工程师推荐考的证书
一篇小短文,带你认识持续集成和Jenkins
如何用delete命令删除文件
ES6 扩展运算符用法
举报/反馈

IT千锋教育

9585获赞 2万粉丝
国内IT职业教育良心机构
关注
0
0
收藏
分享