绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
RabbitMQ 如何确保消息顺序?
2023-05-15 17:52:16

之前有小伙伴说面试中被问到了这个问题,消息中间件如何确保消息顺序,因为松哥之前出过一个 RabbitMQ 的系列教程,所以他就跑来微信上问我,那么今天我们就来稍微捋一捋这个话题。

怎么说呢,感觉在面试中,如果涉及到消息中间件,两个频率比较高的问题,一个是如何确保消息的可靠性,另一个就是如何确保消息有序,如何确保消息可靠性,这个松哥之前已经写过了,公众号后台回复 2020 有文章索引。

1. 整体思路

首先,我们先来聊聊在确保消息有序这件事上的一个整体思路。

大家先来看下面一张图,这是官方提供的 RabbitMQ 消息发送流程图:

大家可以看到,消息从 Publisher 出来之后,先被发送到 Exchange,然后 Exchange 将消息转到 Queue 队列上,后,消费者消费 Queue 上的消息,大致上就是这样一个流程。

那么要确保消息的顺序,只需要确保两点即可:

  1. 发送有序。
  2. 消费有序。

其实只要这两点就够了。

因为当消息发送成功到达队列之后,队列本身就是有序的,先进先出,所以正常情况下,我们是不必考虑队列中消息顺序的问题的。

不过需要小伙伴们注意的是,如果你的消息发送到不同的队列中,那么消息出队的顺序就无法保证了。

所以,从这里我们就总结出个规则,就是如果要确保消息有序,相同类型的消息至少得发到一个队列中,不能发到多个队列中。

2. 发送有序

正常来说,我们发送消息的时候都是按照既定的业务顺序发送的,这点是无疑的。所以发送有序本来不是啥大事,问题在于,有的时候我们的项目是集群化部署,同一个项目有多个实例,当多个不同的实例分布于不同的服务器上运行的时候,都向 MQ 发消息,此时就无法确保消息的有序了。

那么对于这种情况,我们可以考虑使用 Redis 分布式锁来实现,发送消息之前,先去 Redis 上获取到锁,能拿到锁,然后再去发送消息,避免并发发送。至于 Redis 做分布式锁的具体用法我这里就不啰嗦了,之前的 vhr 视频里都讲过了,公号后台回复 vhr 可以查看视频介绍。

这是一个思路。

3. 消费有序

接下来就是消费有序了。

消费有序这里要注意的细节就比较多。

首先,同一个队列只能有一个消费者,如果存在多个消费者,则消费顺序就无法保证了。

其次,同一个队列不能开启并发消费,例如像下面这样的代码:

@RabbitListener(queues = RabbitConfig.JAVABOY_QUEUE_NAME,concurrency = "10")
public void handleMsg(String msg) {
    logger.info("msg:{}", msg);
}

这个相当于建立了 10 个 channel 去同时消费消息,对于这种情况,也是没法保证消费的有序的,因为本地代码执行的快慢、是否抛异常等等,都有可能会影响到消息的顺序。

无法并发消费,就会导致消费性能下降,如果确实对性能又有比较高的要求,那么我们相同类型的队列可以创建多个,然后依然是每一个队列一个消费者即可。

举个简单的例子,比如电商下单的时候,需要给同一个队列发送多条消息,正常发送这些消息当然都是有序的。如果想提高并发能力,那么我们可以设置多个消息队列,跟一个用户相关的订单都发送到同一个消息队列中,然后一个队列对应一个消费者,这样就能保证消息的有序。

好啦,大概就这么多细节。

4. 小结

后,我们再稍微总结下:

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

好啦,以上就是确保 RabbitMQ 消息有序的几个细节。

分享好友

分享这个小栈给你的朋友们,一起进步吧。

中间件
创建时间:2020-02-10 16:02:29
本序列课程主要和大家一起探讨在瞬息万变的互联网大背景下,面对海量数据、高并发、5个9/6个9的稳定性要求等一序列苛刻条件下,如何构建出一个可以既满足业务的快速迭代需求,又稳定高效的互联网系统架构及其设计实践方案。 本课程由技术栈的选型开始引入主题,结合相应的业务,并且考虑相关配合团队的水平、人员组成情况等一序列的因素,主要从选型比较、解决重点/难点问题、实现策略、实施方案的优势优点、成本对比、实施过程的经验教训、实施案例及其感想、后期的改进与维护升级等具体的方面进行一个完整的陈述。 具体技术方面,本课程主要讲述以自我实现与二次开发为主,包括但不局限于:Java的IOC、ORM,Restful等框架、JOB调度系统、ID生成器、HTTP服务器、DFS分布式文件系统、缓存与存储系统、分布式协调器、配置服务、通讯协议、大数据分析等。 后我们将讨论这些系统是如何与业务有机的结合案例与当时如此实施的指导思想,并且大家一起探讨实施过程中如何对于项目实现“快速响应”的控制。 整套课程大体上分为三个部分: 1. 以业务为基础的技术栈开发与选择,这部分以Java为基础,开发各种框架; 2. 高性能中间件的设计实现与在业务中的应用,这部分以c为基础,开发各种高性能中间件; 3. 总结陈述:讨论人、团队、业务、架构、系统、Bug之间的关系,我们整套设计的初衷与指导思想。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • 大嘴
    栈主

小栈成员

查看更多
  • 栈栈
  • VIP讲师团v
  • 58沈剑
  • README
戳我,来吐槽~