当前位置: 首页 > news >正文

深入理解RocketMQ基本原理

🚀 一、RocketMQ 的整体架构长啥样?(一句话:Producer → Broker → Consumer)

核心四块:

  • Producer:消息发送端(同步、异步、单向)
  • Broker:存储 + 投递(RocketMQ 的灵魂)
  • Name Server:注册中心(告诉你 Broker 在哪里)
  • Consumer:消费端(Push/Pull,顺序/并发)

一句话理解:

NameServer 是通讯录,Broker 是邮局,Producer 发信,Consumer 收信。

架构图(脑海里记住它的“松耦合”):

Producer --> NameServer --> Broker --> Consumer

🚀 二、RocketMQ 为什么这么快?核心能力全在 Broker

Broker 是 RocketMQ 的灵魂,它有三大硬核:


1. 存储架构:CommitLog + ConsumeQueue + IndexFile

这套结构太经典,是面试官最喜欢考的。

① CommitLog(顺序写)—— RocketMQ 高吞吐的根本

消息真实内容全部写到一个顺序的 CommitLog 文件里。

特点:

  • 顺序写磁盘(写盘速度接近内存)
  • 大文件分段(1GB)避免过多文件句柄
  • mmap + page cache(零拷贝 + OS 缓存)

要点你要非常清晰:

RocketMQ 不是随机写,是顺序写,所以能顶住高并发写入。

② ConsumeQueue(消费队列)—— 逻辑索引

对每个消费组、每个 Topic 的每个队列都会生成一个 ConsumeQueue。

里面不是消息,只是索引:

(commitlogOffset, messageSize, tagHashCode)

消费者通过它快速定位 CommitLog 里的消息,实现:

  • 有序消费(队列级别)
  • 重试
  • 回溯(指定 offset)

③ IndexFile(按 key 索引)

可以按 Message Key 查消息,例如订单号、业务主键。

不是必须组件,但在排查问题或需要 “按 key 查询” 时很关键。


2. 读写分离 + 异步刷盘 + 内存映射

RocketMQ 的设计完全是为了高性能:

  • 顺序写 CommitLog
  • mmap 将文件映射到内存(减少内核态/用户态上下文切换)
  • 异步刷盘(高吞吐)
  • pageCache + pre-write 优化

一句话:

RocketMQ 利用了操作系统的 page cache,把内存当磁盘来用。


3. 分布式架构:主从 + 多副本存储

RocketMQ 的 HA 机制非常简单直接:

  • Master 写,Slave 从 CommitLog 同步
  • Consumer 可以从 Slave 读(提升读吞吐)
  • 选举机制(Dledger)可实现自动主从切换

你要记住:

RocketMQ 4.x 主从切换不是自动,5.x Dledger 才有自动切换。


🚀 三、消息是怎么流动的?(Producer → Broker → Consumer 全流程)

我讲一个真实的流程,让你脑子里能形成时间线。


1)Producer 发消息

三种发送方式:

  • 同步(业务常用)
  • 异步(适合链路不阻塞)
  • 单向(日志、埋点)

发送过程:

  1. Producer 从 NameServer 获取 Broker 信息
  2. 选择队列(默认轮询每个 MessageQueue)
  3. 写入 Broker(落 CommitLog)
  4. Broker 返回 sendResult

你要特别理解:

一个 Topic(T)会分成多个队列(T-Q1、T-Q2…),Producer 是向队列发的。


2)Broker 存储消息

存储流程:

消息进入内存 → 顺序写 CommitLog → 构建 ConsumeQueue → 异步刷盘 → HA 同步给 Slave

关键点:

  • 消息真正落地在 CommitLog
  • ConsumeQueue 是异步构建的索引

3)Consumer 消费消息

两种模式:

A. 集群模式(均摊消息)

同一个 Consumer Group 多个实例 → 均分队列:

例如 4 个队列、2 个消费者:

C1: Q1, Q3
C2: Q2, Q4

B. 广播模式(每个实例都消费)

用得少,业务上要小心。


4)消费进度(offset)怎么管理?

  • 由 broker 管理:RocketMQ 默认
  • 由 consumer 管理:广播模式

并且 offset 存储在:

broker: /store/config/consumerOffset.json

面试一定要说:

RocketMQ 的消费位置是按 queue + group 来递增的,不是按消息 ID!


🚀 四、RocketMQ 的顺序消息到底怎么实现?

面试必问。

顺序的关键不是什么高大上的算法,其实非常朴素:

核心原则:同一业务 key 的消息必须进入同一个队列。

RocketMQ 顺序能力分两种:


1)分区顺序(常用):保证某个业务 key 的顺序

做法:

  • 自定义 MessageQueueSelector
  • 根据 orderId 选择固定 queue

这样:

订单 10001 → 队列 3
订单 10001 → 队列 3

消费者按队列拉取,自然顺序就保证了。


2)全局顺序(几乎不用):整个 Topic 只有一个队列

吞吐会变得惨不忍睹。


🚀 五、RocketMQ 的消息重试机制(你必须掌握)

Producer 成功发送,但 Consumer 可能消费失败。

RocketMQ 的重试逻辑:

1)Consumer 端失败 → 返回 RECONSUME_LATER

Broker 会把消息投递到 retry topic,如:

%RETRY%myGroup

然后根据延迟级别重新投递:

  • 10s
  • 30s
  • 1m
  • 2m
  • ...
  • 最长 2h

重试 16 次仍失败?

2)进入死信队列(DLQ)

队列名:

%DLQ%myGroup

🚀 六、RocketMQ 为什么要分队列?(关键知识点)

你一定要知道 RocketMQ 不是对 Topic 直接操作,而是:

Topic = 多个队列的集合(MessageQueue)

这样做有三大好处:

  1. Producer 并发写入不同队列 → 提升写吞吐
  2. Consumer 拉取分队列处理 → 提升消费并行度
  3. 队列是顺序消息的天然单位 → 保证顺序性

这是 RocketMQ 的设计核心,不理解这点你永远搞不懂顺序消息。


🚀 七、RocketMQ 的事务消息(最终一致性神器)

流程类似两阶段提交:

  1. Producer 发送 half message(不让消费者看到)
  2. 执行本地事务
  3. 返回 commit / rollback
  4. 如果 Producer 崩溃,Broker 通过回查接口询问状态

事务消息用得不多,但属于面试必杀点。

记住一句话:

事务消息不是强一致,而是最终一致。


🚀 八、RocketMQ 的零拷贝和 mmap 是怎么提升性能的?

RocketMQ 使用 mmap 将文件映射到内存。

好处:

  • 读写不需要用户态/内核态切换
  • 利用 OS page cache
  • 异步持续刷盘

而且 RocketMQ 还用了:

  • writeBuffer(预写内存池)
  • transientStorePool(临时缓存池)
  • directByteBuffer(堆外内存)

RocketMQ 的核心性能优化点全部围绕 顺序写 + mmap + 异步刷盘


🚀 九、一张图总结 RocketMQ 原理全景(必背)

       NameServer↑
Producer → Broker(Master) → Consumer↑Slave

Broker 内部:

CommitLog(顺序写)↓ 构建
ConsumeQueue(按队列索引)↓
Consumer 拉取

消息生命周期:

发送 → 顺序写 CommitLog → 生成索引 → 同步 slave → consumer 消费 → 更新 offset

🚀 十、你要的工程师视角总结(面试 + 实战双杀)

你脑海里记住下面几句话,这就是 RocketMQ 的精髓:

  1. RocketMQ 的吞吐靠顺序写磁盘,不是靠内存跳舞。
  2. Topic 是逻辑概念,真正的并发单位是队列。
  3. ConsumeQueue 是索引,不是消息本体。
  4. 顺序消息本质是“同类消息进同一队列”。
  5. 重试和死信队列是 Broker 的机制,和 Consumer 逻辑无关。
  6. 事务消息是最终一致,不是强一致。
  7. Broker 是 RocketMQ 的灵魂,不懂存储就不懂 RocketMQ。
http://www.jsqmd.com/news/64290/

相关文章:

  • 内部网关协议——OSPF 协议(开放最短路径优先)(链路状态路由协议) - 指南
  • 剖析全球网络入侵:中国国家级APT组织的技战术与防御指南
  • 限制
  • Revit API 创建模仿官方的实时显示的Dockablepanel
  • 企业智能体化:从系统堆叠到智能体矩阵的组织进化
  • Kafka工作流程及文件存储机制 - 详解
  • 实用指南:微软加速在亚洲扩展云基础设施,推动区域数字化跨越式发展
  • 【GitHub热门项目】(2025-11-09) - 详解
  • 深入解析:Nginx优化与防盗链
  • [GESP202312 三级] 小猫分鱼
  • markdown文档格式分析,再使用python对md文件进行结构化拆解
  • CMake Uninstall
  • 实用指南:通过约束编程优化医疗智能系统的伦理风险降低(下)
  • 【Java 开发日记】大家来说一下 Mybatis 的缓存机制
  • Day12-20251206
  • 悬架设计计算工具:开启悬架设计学习与实践的钥匙
  • Solon AI 开发学习17 - generate - 使用复杂提示语
  • c++笔记
  • 别再发愁!对比多款后锁定这6个型号,挑选高中学习机,不花冤枉钱
  • [UVA1316 Supermarket]
  • 使用typora来写md文件时配置文件存放图片的路径
  • 靠谱厂房拆迁法律机构排行榜 2026:专业解析与高性价比解决方案
  • 滥用ESC10:通过注册表配置不当实现权限提升的ADCS攻击分析
  • [NOI2015 程序自动分析]
  • 【基础】Unity着色器网格和计算对象介绍
  • 【基础】Unity着色器网格和计算对象介绍
  • 基于大内容的保险数据管理与可视化分析平台
  • 深入解析:C++ 闭散式和开散式的模拟实现
  • 基于先验地图的无人机路径规划
  • 首单半价对话框的实现