RocketMQ 架构组成与核心概念详解(偏实战视角)
这份文档目标:把 RocketMQ “是什么 + 怎么跑起来 + 为什么这样设计” 讲清楚。读完你应该能:
- 画出 RocketMQ 的核心组件图
- 理解 Topic/Queue/Group/Offset/Rebalance 这些概念之间的关系
- 看懂消息从 Producer 到 Consumer 的完整链路
- 对 RocketMQ 4.x 与 5.x 的架构差异有基本认知(不纠结细枝末节)
目录
- 1. RocketMQ 解决什么问题
- 2. 一张图看全链路
- 3. 核心组件
- 4. 核心概念与模型
- 5. 存储与读写路径(为什么吞吐高)
- 6. 常见能力与适用场景
- 7. RocketMQ 4.x vs 5.x(你需要知道的差异)
- 8. 常见误区(踩坑预警)
- 9. 参考链接
1. RocketMQ 解决什么问题
RocketMQ 属于 分布式消息中间件,核心价值就三件事:
- 解耦:上游发消息不关心下游是谁、什么时候处理。
- 削峰填谷:流量峰值先写 MQ,消费者按能力慢慢处理。
- 异步与事件驱动:订单创建→支付→库存→物流,一堆系统可以靠事件串起来。
它的设计目标是:高吞吐 + 可水平扩展 + 可用性还不错。在传统业务(交易/营销/风控/日志)里非常常见。
2. 一张图看全链路
下面是最典型的 RocketMQ 4.x/5.x 通用链路(5.x 可能多一层 Proxy):
+-----------+ (route/meta) +------------+
| Producer | <----------------------> | NameServer |
+-----------+ +------------+
|
| send(msg)
v
+-----------+ store/replicate +-----------+
| Broker | <---------------------> | Broker | (Master/Slave 或者 DLedger/Controller)
+-----------+ +-----------+
^
| pull / long-poll / push-style
|
+-----------+
| Consumer | (Consumer Group)
+-----------+
你可以把它理解成:
- NameServer:目录服务/路由中心
- Broker:真正存储和投递消息的“服务器集群”
- Producer/Consumer:客户端(SDK)
3. 核心组件
3.1 Producer
Producer 就是“发消息的人”。
关键点:
- Producer 不直接把消息发给 NameServer,它会从 NameServer 拉取 Topic 的路由信息,然后直连某个 Broker 发送。
- Producer 发送通常有重试与故障规避(例如切换到其他 Broker/队列)。
- Producer 往往需要做:发送确认(ACK)、失败重试、幂等/去重(业务层)。
3.2 Consumer
Consumer 是“收消息的人”。常见模型是:同一个 Consumer Group 内的多个实例共同消费同一份 Topic 数据。
关键点:
- Consumer 会定期从 NameServer/Broker 维护路由/订阅信息。
- Consumer 的消费进度由 Offset 表示,决定“从哪里开始读”。
- RocketMQ 默认语义更偏 至少一次(at-least-once):异常重试可能导致重复投递,因此业务通常要做幂等。
3.3 Broker
Broker 是 RocketMQ 的“核心服务器”,负责:
- 接收消息、存储消息
- 提供按 Topic/Queue/Offset 的查询与拉取
- 做复制(HA)、刷盘、索引维护
- 管理消费者进度(不同版本/模式进度存储位置可能不同)
Broker 内部你可以拆成三块能力:
- 网络层:接收 send/pull 请求(Netty)
- 存储层:CommitLog/ConsumeQueue/IndexFile
- 调度层:长轮询、重试、延时消息、事务回查等
3.4 NameServer
NameServer 的定位很“朴素”:
- 存路由信息(Topic → Broker/Queue)
- Broker 启动后向 NameServer 注册(心跳)
- Producer/Consumer 从 NameServer 拉取路由
特点:
- NameServer 本身 无状态、可多节点部署
- 路由信息是最终一致的(不是强一致数据库)
- NameServer 不参与消息存储,所以它挂了不等于消息丢,但新路由更新会受影响
3.5 Proxy(RocketMQ 5.x 常见)
RocketMQ 5.x 引入/强化 Proxy 的原因,简单讲是两点:
- 更云原生:把“计算/接入层”做成可弹性扩展的一层
- 协议与多语言更友好:Proxy 可以统一做认证鉴权、协议适配等
一些发行版/云厂商会强推 Proxy 模式:
Producer/Consumer -> Proxy -> Broker
注意:Proxy 多一跳,可能影响端到端延迟;但运维和接入会更舒服。
3.6 Controller / DLedger(高可用与元数据)
这是偏“进阶架构”的一块:RocketMQ 为了做到更强的 HA/选主/复制,会引入:
- Master-Slave 复制:传统模式,主写从读/备
- DLedger:基于 Raft 的复制/选主机制(常用来增强一致性)
- Controller(5.x 常见):更集中地管理元数据与 Broker 高可用相关逻辑(不同版本实现细节不完全一致)
你可以粗暴理解为:
Master-Slave 更像“主库 + 从库”;DLedger/Controller 更像“分布式一致性集群”。
3.7 Console / Admin
- RocketMQ Console:常用 Web 管理界面(Topic、Group、Offset、堆积、消息查询等)
- Admin 工具:创建 Topic、重置 Offset、查看堆积等运维动作(高危操作很多,慎用)
4. 核心概念与模型
4.1 Topic、MessageQueue
Topic:消息的逻辑分类(类似“频道”)。Producer 发到 Topic,Consumer 订阅 Topic。
MessageQueue(简称 Queue):Topic 的分片。一个 Topic 会有多个 Queue。
- Queue 是 RocketMQ 最小的存储/并行单位
- 你想要更高并行度/吞吐,通常就是增加 Queue 数量(但别乱加,会影响 Rebalance 频率、文件数量、运维复杂度)
关系:
Topic = { Queue0, Queue1, Queue2, ... }
4.2 Message、Tag、Key、Property
Message:真正的数据载体(body + metadata)。
常见字段:
- body:业务数据(建议用 JSON/Protobuf 等)
- Tag:轻量分类,常用于消费端过滤(例如订单:CREATE / PAY / CANCEL)
- Key:业务唯一标识(例如 orderId),用于查消息、排查问题
- Properties:扩展属性(例如 traceId、bizType、tenantId)
经验:
- Tag 用于“粗粒度过滤”,Key 用于“精准定位”,body 里才放完整业务数据。
4.3 Producer Group、Consumer Group
Producer Group:
- 主要用于管理与容灾(同一类 Producer 的集合)
- 在某些特性(如事务消息)里,Producer Group 也会参与语义(比如回查)
Consumer Group:
- 同一个 Group 下的多个 Consumer 实例,共同消费同一 Topic 的消息
- Group 是 RocketMQ 做负载均衡与 Rebalance 的基本单位
4.4 Offset(消费进度)
Offset = “某个 Queue 消费到哪条了”。
它通常长这样:
(Topic, QueueId) -> currentOffset
Consumer 消费时会:
- 从 Broker 拉取一批消息(从 currentOffset 开始)
- 处理成功后提交/更新 Offset
- 下次继续从新的 Offset 消费
4.5 Push vs Pull
RocketMQ 文档里经常说“Push 模式”和“Pull 模式”,但真实情况更像:
- Pull:Consumer 主动拉(你可以自己控制频率、批量、退避)
- Push:SDK 封装成“看起来像推”,本质仍然是 Consumer 侧循环 Pull + 长轮询
所以 Push 更像是 “拉取的封装”。
4.6 消费模式:集群 vs 广播
-
集群模式(Clustering):同一个 Consumer Group 内,一条消息只会被其中一个实例消费
适合业务处理、订单、支付等
-
广播模式(Broadcasting):同一个 Group 内,每个实例都会收到全量消息
适合本地缓存刷新、配置变更通知等
4.7 Rebalance(负载均衡)
Rebalance:当 Consumer 实例数量变化、Topic 队列数量变化、路由变化时,RocketMQ 会重新分配 Queue → Consumer 的映射。
核心效果:
- 集群模式下:同一 Group 内,每个 Queue 同一时刻只会分配给一个 Consumer 实例
- 新实例加入/旧实例宕机时:队列会重新分配 → 消费“归属”发生变化
Rebalance 的直觉类比:
就像把一堆“分区(Queue)”分配给一组“工人(Consumers)”。工人变多/变少,就得重新分配任务。
4.8 重试与死信(Retry / DLQ)
当 Consumer 处理失败:
- RocketMQ 通常会把消息投递到 重试队列(Retry Topic)
- 多次重试仍失败 → 进入 死信队列(DLQ)
经验:
- DLQ 不是“垃圾桶”,是“你必须处理的异常业务入口”
- DLQ 消息一定要有补偿方案(人工/自动修复)
5. 存储与读写路径(为什么吞吐高)
RocketMQ 的高吞吐,很大程度来自它的存储设计:顺序写 CommitLog + 异步构建索引。
5.1 CommitLog、ConsumeQueue、IndexFile
可以把 Broker 的存储理解为“三层结构”:
- CommitLog(物理日志)
- 所有消息按到达顺序追加写入(append-only)
- 这是“事实真相(source of truth)”,消息最终都在这里
- ConsumeQueue(逻辑队列索引)
- 按 (Topic, QueueId) 组织的“逻辑索引”
- 记录每条消息在 CommitLog 的偏移、大小、tag 等
- Consumer 拉取消息时,通常是先定位 ConsumeQueue,再去 CommitLog 读具体内容
- IndexFile(可选的查询索引)
- 常用于按 Key 查询消息(排障很有用)
简单图:
CommitLog: [ msg1 ][ msg2 ][ msg3 ][ msg4 ] ... (顺序写)
ConsumeQueue:
TopicA-Queue0 -> (offset,size,tag) (offset,size,tag) ...
TopicA-Queue1 -> ...
TopicB-Queue0 -> ...
IndexFile:
key=orderId123 -> CommitLogOffset=...
5.2 Flush:异步刷盘 vs 同步刷盘
Broker 写入消息后要落盘,常见两种刷盘策略:
- 异步刷盘(Async Flush):吞吐高,但极端情况下(机器断电)可能丢“已返回成功但未刷盘”的数据
- 同步刷盘(Sync Flush):更安全,但吞吐会下降
选型建议:
- 金融/交易强一致链路:优先 Sync Flush(或更强 HA 组合)
- 普通业务:Async Flush + 合理复制策略 + 业务可补偿,往往更划算
5.3 主从复制:同步复制 vs 异步复制
复制策略同样两类:
- 异步复制:主节点先返回 ACK,再慢慢复制到从节点(性能好,风险略高)
- 同步复制:写入主从都确认后才 ACK(更安全,性能会受影响)
很多“消息不丢”的最佳实践,基本就是在 刷盘 + 复制 这两处下功夫。
6. 常见能力与适用场景
6.1 顺序消息
顺序消息本质:同一业务键的消息进同一个 Queue,并且 Consumer 对该 Queue 串行处理。
你需要关心:
- Producer:按 shardingKey 选择同一个 queue
- Consumer:使用有序消费(单线程/锁队列)
代价:
- 并行度下降(同一键必须串行)
- Rebalance、失败重试会更敏感(顺序容易被打断)
6.2 延时/定时消息
延时消息:现在发,过一段时间才让 Consumer 看见。适用于:
- 订单超时关闭
- 支付超时检查
- 异步补偿重试
注意:
- 延时不是“精准定时任务”,更多是“延后投递”
- 大量延时消息要评估 Broker 的调度与存储压力
6.3 事务消息
事务消息解决:本地事务与消息发送的一致性(典型:下单成功才发“订单已创建”事件)。
基本流程:
- Producer 发送半消息(Half Message)
- Producer 执行本地事务
- 根据事务结果提交/回滚消息
- Broker 若长时间未收到结果,会回查 Producer(回查接口要能根据业务键判断事务状态)
6.4 消息过滤:Tag / SQL
- Tag 过滤:简单、快、常用
- SQL 过滤:更灵活(基于属性表达式),但更复杂、也更吃资源
经验:能用 Tag 就别上 SQL。
6.5 轨迹 Trace 与监控
建议至少看这些指标:
- Producer 发送成功率、发送耗时分位数
- Consumer 消费耗时、失败率、重试率
- 消费堆积(lag):Topic/Group 维度堆积量
- Broker:磁盘、PageCache、IO、线程池、堆外内存等
7. RocketMQ 4.x vs 5.x(你需要知道的差异)
你不需要把版本细节背下来,但至少要知道这些趋势:
- 4.x:经典架构,Producer/Consumer 直连 Broker,NameServer 做路由
- 5.x:更云原生,常见会引入 Proxy、强化多协议与接入层能力,并在 HA/元数据管理上有更多组件化设计
一句话总结:
4.x 更像“传统自建集群”;5.x 更像“云上拆分成接入层 + 存储层 + 元数据/控制面”。
8. 常见误区(踩坑预警)
-
“我用了 MQ,所以一定不丢消息”
错。你要同时关注:Producer 发送确认、Broker 刷盘/复制、Consumer offset 提交、重试/DLQ。 -
Queue 数量越多越好
不一定。队列多会增加文件/索引数量与 Rebalance 成本,还可能导致小流量队列“稀疏访问”。 -
把 MQ 当数据库查
MQ 擅长流式投递,不擅长随机查询与长期存储。需要数据沉淀用数据库/数仓/日志系统。 -
忽略幂等
RocketMQ 默认至少一次,重复消费是常态,不是异常。业务必须设计幂等或去重。
9. 参考链接
- Apache RocketMQ 官方文档:核心概念(Consumer Group、Offset、Push/Pull 等)
- Apache RocketMQ 官方文档:组件介绍(Producer/Consumer/NameServer/Broker)
- Apache RocketMQ 官方文档:消息队列(MessageQueue)与消息模型
- Apache RocketMQ 官方文档:消息存储策略(CommitLog / ConsumeQueue 等)
- RocketMQ 5.x 部署/组件说明(NameServer、Broker、Proxy 等)
1351

被折叠的 条评论
为什么被折叠?



