RocketMQ
为交易场景生的消息队列,事务和延迟消息是原生能力
RocketMQ 是阿里在大促场景里磨出来的消息队列,双十一的峰值流量是它的主场。相比 Kafka,它把国内业务最常问的几件事做成了原生功能:事务消息、18 级延迟消息、严格顺序消息,还有一套很轻的路由中心 NameServer。
它解决什么问题
下单成功后要通知库存、积分、物流,还得保证“本地事务成功才发消息”。用 Kafka 要自己写本地消息表兜底,用 RocketMQ 一个事务消息就解决了。
真实场景:典型场景:用户下单,订单库写入成功后发一条事务消息,库存服务扣减。订单库回滚了,消息就不会被投递出去。
核心概念
每个概念一句话 + 一个类比。点击卡片看更详细的解释。
Producer
发消息的一方,支持同步、异步、单向三种发送
类比:寄快递的人
看概念详情Consumer
收消息的一方,分 Push 和 Pull 两种模式
类比:收快递的人
看概念详情ConsumerGroup
一组消费者分摊队列,组内一条消息只消费一次
类比:一个客服组的同事轮流接单
看概念详情Broker
存消息、投递消息的服务器
类比:快递驿站
看概念详情Topic
一类消息的集合,发送时必须指定
类比:按品类分的收件筐
看概念详情MessageQueue
Topic 的分区,消息真正存放和并行消费的单位
类比:驿站里的货架,一个 Topic 有好几个货架
看概念详情NameServer
无状态的轻量路由注册中心,告诉客户端该找哪个 Broker
类比:查“这个快递该去哪个驿站”的地图
看概念详情广播 / 集群模式
集群模式组内分摊,广播模式每个消费者都收全量
类比:群发通知(广播)vs 派单给一个人(集群)
看概念详情数据流转动画
跟着步骤看一条数据从进入系统到被处理完的完整路径,可以暂停、重播和调速。
生产者发消息 + 消费者组负载均衡
← 左右滑动查看完整流程图 →
Producer 向 NameServer 询问 order-topic 分布在哪些 Broker 上。
提示:注意 NameServer 只给路由、不存消息;Queue 才决定并行度和顺序。 悬停图中的节点可以看概念解释。
优劣势
短句说清适合什么、不适合什么,选型时先看这一栏。
- 原生事务消息,解决“本地事务 + 发消息”一致性
- 原生 18 级延迟消息,订单超时关单不用自己扫表
- 单 Queue 严格有序,顺序消费开箱可用
- NameServer 无状态,运维比 Kafka 的 ZK 轻
- 吞吐低于 Kafka,社区和生态规模也小一些
- 延迟消息只有 18 个固定档位,不能任意秒数
- 客户端以 Java 为主,其他语言 SDK 相对弱
- Topic 数量过多时性能下降明显
常见使用场景
每个场景都配一句「为什么用它」。
订单超时自动关单
下单时发一条 30 分钟延迟消息,到点消费,检查状态后关单。
为什么用它:延迟消息是原生能力,不用自己写定时扫表任务。
分布式事务最终一致
订单库写入后发事务消息,库存服务消费扣减,失败则回查补偿。
为什么用它:半消息 + 回查机制保证“本地事务成功,消息一定发出去”。
大促削峰
秒杀请求先进 MQ,后端按自己的能力慢慢消费。
为什么用它:RocketMQ 在阿里双十一场景验证过,堆积能力强。
同类对比
和同赛道的组件并排看,差异一目了然。
一句话:吞吐选 Kafka,业务语义选 RocketMQ,路由灵活和轻量选 RabbitMQ。三者不是替代关系,很多公司同时用两个。
常见问题
上手第一个月最容易卡住的地方。
Q1顺序消费怎么实现?
发送时用 MessageQueueSelector 按订单号把同一订单的消息投到同一个 Queue,消费端用 MessageListenerOrderly 加锁顺序消费。注意:全局顺序要把 Topic 设成 1 个队列,几乎没人这么做。
Q2延迟消息怎么用?
发消息时设置 delayTimeLevel(1~18,对应 1s 到 2h)。RocketMQ 5.x 支持任意时间定时消息(timer message),需要 Broker 开启 timerWheel 支持。
Q3事务消息的原理?
先发半消息(对消费者不可见)→ 执行本地事务 → 提交或回滚。如果 Broker 没收到确认,会定时回查生产者的本地事务状态,最多 15 次,仍未知则丢弃并告警。
Q4广播模式和集群模式的区别?
集群模式(默认)组内分摊,一条消息只被一个消费者处理;广播模式每个消费者都收全量,offset 存在本地。广播模式不能做消息重投,也不保证消费进度。
Q5消息堆积了怎么办?
先看是消费慢还是消费挂了。消费慢就加消费者(不超过 Queue 数)或提高批量拉取;Queue 不够就扩容 Queue。RocketMQ 堆积不影响写入,但磁盘满了会拒绝写入。