详解RocketMQ 顺序消费机制
摘要:顺序消息是指对于一个指定的 Topic ,消息严格按照先进先出(FIFO)的原则进行消息发布和消费,即先发布的消息先消费,后发布的消息后消费。
本文分享自华为云社区《RocketMQ 顺序消费机制》,作者: 勇哥java实战分享 。
顺序消息是指对于一个指定的 Topic ,消息严格按照先进先出(FIFO)的原则进行消息发布和消费,即先发布的消息先消费,后发布的消息后消费。
顺序消息分为分区顺序消息和全局顺序消息。
1、分区顺序消息
对于指定的一个 Topic ,所有消息根据 Sharding Key 进行区块分区,同一个分区内的消息按照严格的先进先出(FIFO)原则进行发布和消费。同一分区内的消息保证顺序,不同分区之间的消息顺序不做要求。
- 适用场景:适用于性能要求高,以 Sharding Key 作为分区字段,在同一个区块中严格地按照先进先出(FIFO)原则进行消息发布和消费的场景。
- 示例:电商的订单创建,以订单 ID 作为 Sharding Key ,那么同一个订单相关的创建订单消息、订单支付消息、订单退款消息、订单物流消息都会按照发布的先后顺序来消费。
2、全局顺序消息
对于指定的一个 Topic ,所有消息按照严格的先入先出(FIFO)的顺序来发布和消费。
- 适用场景:适用于性能要求不高,所有的消息严格按照 FIFO 原则来发布和消费的场景。
- 示例:在证券处理中,以人民币兑换美元为 Topic,在价格相同的情况下,先出价者优先处理,则可以按照 FIFO 的方式发布和消费全局顺序消息。
全局顺序消息实际上是一种特殊的分区顺序消息,即 Topic 中只有一个分区,因此全局顺序和分区顺序的实现原理相同。
因为分区顺序消息有多个分区,所以分区顺序消息比全局顺序消息的并发度和性能更高。

消息的顺序需要由两个阶段保证:
- 消息发送
如上图所示,A1、B1、A2、A3、B2、B3 是订单 A 和订单 B 的消息产生的顺序,业务上要求同一订单的消息保持顺序,例如订单 A 的消息发送和消费都按照 A1、A2、A3 的顺序。
如果是普通消息,订单A 的消息可能会被轮询发送到不同的队列中,不同队列的消息将无法保持顺序,而顺序消息发送时 RocketMQ 支持将 Sharding Key 相同(例如同一订单号)的消息序路由到一个队列中。

- 消息消费
消费者消费消息时,需要保证消息消费顺序和存储顺序一致,最终实现消费顺序和发布顺序的一致。

我们知道负载均衡服务是客户端开始消费的起点。在负载均衡阶段,并发消费和顺序消费并没有什么大的差别,最大的差别在于:向 Borker 申请锁 。
消费者根据分配的队列 messageQueue ,向 Borker 申请锁 ,如果申请成功,则会拉取消息,如果失败,则定时任务每隔20秒会重新尝试。

见上图,顺序消费核心流程如下:
1、 组装成消费对象
2、 将请求对象提交到消费线程池

和并发消费不同的是,这里的消费请求包含消费快照 processQueue ,消息队列 messageQueue 两个对象,并不对消息列表做任何处理。
3、 消费线程内,对消费队列加锁

4、 从消费快照中取得待消费的消息列表

消费快照 processQueue 对象里,创建了一个红黑树对象 consumingMsgOrderlyTreeMap 用于临时存储的待消费的消息。
5、 执行消息监听器

执行监听器逻辑容易理解,消费快照的消费锁 consumeLock的作用是:防止 Rebalance 线程把当前消费的 MessageQueue 对象移除掉。
6、 处理消费结果
消费成功时,首先计算需要提交的偏移量,然后更新本地消费进度。

消费失败时,分两种场景:
- 假如已消费次数小于最大重试次数,则将放入对象 consumingMsgOrderlyTreeMap 用例临时存储的待消费的消息,重新加入到消费快照红黑树msgTreeMap中,然后使用定时任务尝试重新消费。
- 假如已消费次数大于等于最大重试次数,则将失败消息发送到 Broker ,Broker 接收到消息后,会加入到死信队列里 , 最后计算需要提交的偏移量,然后更新本地消费进度。
我们做一个关于顺序消费的总结:
- 顺序消费需要由两个阶段消息发送和消息消费协同配合,底层支撑依靠的是 RocketMQ 的存储模型;
- 顺序消费服务启动后,通过三把锁的机制,消息队列 messageQueue 的数据都会被消费者实例单线程的执行消费;
- 假如消费者扩容,消费者重启,或者 Broker 宕机 ,顺序消费也会有一定几率较短时间内乱序,所以消费者的业务逻辑还是要保障幂等。
详解RocketMQ 顺序消费机制的更多相关文章
- 一次 RocketMQ 顺序消费延迟的问题定位
一次 RocketMQ 顺序消费延迟的问题定位 问题背景与现象 昨晚收到了应用报警,发现线上某个业务消费消息延迟了 54s 多(从消息发送到MQ 到被消费的间隔): 2021-06-30T23:12: ...
- 异常处理器详解 Java多线程异常处理机制 多线程中篇(四)
在Thread中有异常处理器相关的方法 在ThreadGroup中也有相关的异常处理方法 示例 未检查异常 对于未检查异常,将会直接宕掉,主线程则继续运行,程序会继续运行 在主线程中能不能捕获呢? 我 ...
- 十图详解tensorflow数据读取机制(附代码)转知乎
十图详解tensorflow数据读取机制(附代码) - 何之源的文章 - 知乎 https://zhuanlan.zhihu.com/p/27238630
- 浏览器 HTTP 协议缓存机制详解--网络缓存决策机制流程图
1.缓存的分类 2.浏览器缓存机制详解 2.1 HTML Meta标签控制缓存 2.2 HTTP头信息控制缓存 2.2.1 浏览器请求流程 2.2.2 几个重要概念解释 3.用户行为与缓存 4.Ref ...
- RocketMQ(7)---RocketMQ顺序消费
RocketMQ顺序消费 如果要保证顺序消费,那么他的核心点就是:生产者有序存储.消费者有序消费. 一.概念 1.什么是无序消息 无序消息 无序消息也指普通的消息,Producer 只管发送消息,Co ...
- 详解java动态代理机制以及使用场景
详解java动态代理机制以及使用场景 https://blog.csdn.net/u011784767/article/details/78281384 深入理解java动态代理的实现机制 https ...
- RocketMQ 顺序消费只消费一次 坑
rocketMq实现顺序消费的原理 produce在发送消息的时候,把消息发到同一个队列(queue)中,消费者注册消息监听器为MessageListenerOrderly,这样就可以保证消费端只有一 ...
- RocketMq顺序消费
部分内容出处 https://www.jianshu.com/p/453c6e7ff81c rocketmq内部有4个默认的队里,在发送消息时,同一组的消息需要按照顺序,发送到相应的mq中,同一组 ...
- 51.RocketMQ 顺序消费
大部分的员工早上的心情可能不会很好,因为这时想到还有很多事情要做,压力会大点,一般到下午4点左右,状态会是一天中最好的,因为这时大部分的工作做得差不多了,又快要下班了,当然也不是绝对.要注意记录各下属 ...
- 详解 Redis 内存管理机制和实现
Redis是一个基于内存的键值数据库,其内存管理是非常重要的.本文内存管理的内容包括:过期键的懒性删除和过期删除以及内存溢出控制策略. 最大内存限制 Redis使用 maxmemory 参数限制最大可 ...
随机推荐
- 获取JSON数据_获取二进制数据
#百度jk图片 import requests # 请求头 header={"user-agent": "Mozilla/5.0 (Windows NT 10.0; WO ...
- MySQL 中索引是如何实现的,有哪些类型的索引,如何进行优化索引
MySQL 中的索引 前言 索引的实现 哈希索引 全文索引 B+ 树索引 索引的分类 聚簇索引(clustered index) 非聚簇索引(non-clustered index) 联合索引 覆盖索 ...
- vue中关于对象的监听与数组的监听
数组: 数组可监听到的方法:'push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse' 如果是根据索引改变值,需要使用vue.$set ...
- JQ的尺寸类
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 快来玩AI画图!StableDiffusion模型搭建与使用入门~
前言 最近AI很火,先是AI画图,然后就ChatGPT,后者我已经用了一段时间了,用来写作文挺不错的,但OpenAI屏蔽了中国IP,加上用户太多啥的,用起来没那么爽,但没办法全球只此一家,只能捏着鼻子 ...
- Flask快速入门day 01(flask介绍、快速使用、配置文件、路由系统)
目录 Flask框架 前言: 一.flask介绍 1.介绍 2.使用两种协议编写web 二.flask快速使用 1.快速使用: 2.使用flask编写登录小案例 2.1 login.html 2.2 ...
- 19.3 对FAT的支持(harib16c)
19.3 对FAT的支持(harib16c) 问题:可以正确显示文件开头的512字节的内容,但大于512字节的部分不能正确显示(可能会显示其他文件). 问题本质:磁盘可能将大于512字节的文件离散的保 ...
- 投资组合计算分析——R语言
"投资组合"是指金融资产(如股票.债券和现金)的任何组合.投资组合有很多类型,包括市场投资组合和零投资投资组合.可以使用以下任何一种投资方法和原则来管理投资组合的资产分配:股息加权 ...
- vue指令系统之文本指令
目录 什么是指令系统 文本指令 v-text指令 v-html指令 v-show v-if 什么是指令系统 指令系统是VUE提供的,语法为 v-xx 写在标签属性中的,系统都称之为指令 文本指令 文本 ...
- IO流中「线程」模型总结
目录 一.基础简介 二.同步阻塞 1.模型图解 2.参考案例 三.同步非阻塞 1.模型图解 2.参考案例 四.异步非阻塞 1.模型图解 2.参考案例 五.Reactor模型 1.模型图解 1.1 Re ...