消息队列精进之路

消息队列相关问题一网打尽
帅旋
关注
充电
IT宅站长,技术博主,架构师,全网id:arthinking。

消息队列如何保证消息消费的顺序性?

发布于 2024-03-13 | 更新于 2024-06-25

这个跟具体的消息中间件存储架构有关以RocketMQ为例,顺序消费分为全局顺序消费和分区顺序消费:

  • 全局顺序:同一个Topic下的消息,所有消息按照严格的FIFO顺序进行发布和消费。适用于:性能要求不高,所有消息严格按照FIFO进行发布和消费的场景;
  • 分区顺序:同一个Topic下,根据消息的特定业务ID进行sharding key分区,同一个分区内的消息按照严格的FIFO顺序进行发布和消费。适用于:性能要求高,在同一个分区中严格按照FIFO进行发布和消费的场景。

一般情况下,生产者是会以轮训的方式把消息发送到Topic的消息队列中的:

image-20211017213242909

在同一个Queue里面,消息的顺序性是可以得到保证的,但是如果一个Topic有多个Queue,以轮训的方式投递消息,那么就会导致消息乱序了。

为了保证消息的顺序性,需要把保持顺序性的消息投递到同一个Queue中。

具体来说,分为生产端的投递消息的顺序性和消费端消费消息的顺序性。

具体可以参考:消息队列#RocketMQ#顺序消费


简单总结:

  • 生产端:RocketMQ提供了MessageQueueSelector接口,可以用来实现自定义的选择投递的消息队列的算法,比如可以针对同一个订单号与消息队列个数取模,保证让同一个订单号的消息落入同一个消息队列,但是如果某个Master阶段挂了,导致Topic消息队列数量发生变化,就会导致同一个订单分散到不同的消息队列里面了,导致不能顺序消费消息。如果要解决这个问题,只能牺牲failover特性了,即放弃生产端的高可用;
  • 消费端:RocketMQ中提供了MessageListenerOrderly,该对象用于有顺序收异步传递的消息,一个队列对应一个消费线程。问题:如果遇到某条消息消费失败,并且无法跳过,那么消息队列的消费进度就会停滞。

本文作者: 帅旋

本文链接: https://www.itzhai.com/columns/faqs/mq/how-to-ensure-message-consumption-orderliness.html

版权声明: 版权归作者所有,未经许可不得转载,侵权必究!联系作者请加公众号。

×
IT宅

关注公众号及时获取网站内容更新。

请帅旋喝一杯咖啡

咖啡=电量,给帅旋充杯咖啡,他会满电写代码!

IT宅

关注公众号及时获取网站内容更新。