RocketMQ
架构图

三种消息队列对比

使用
配置文件

发送
在业务中注入即可使用
1 |
|
三种发送方式
同步发送==可靠性最高==:

异步发送:

单向发送:

五种消息类型
顺序消息:

延时消息:

批量消息:

事务消息:

过滤消息:

接收
使用示例:

消费者类型:

Pull模式手动拉取:

一、消息队列的核心作用
1. 异步
- 主业务快速返回:将非核心业务(如发短信、写日志)放入消息队列异步处理,主链路无需等待。
- 提升响应速度:例如订单完成后发送积分通知,用户无需等待积分处理完毕即可看到下单成功。
2. 解耦
- 只关心消息到达队列:生产者只负责将消息发送到队列,不关心下游具体由谁处理、如何处理。
- 下游灵活扩展:新增消费者或修改消费逻辑不影响上游业务,降低系统间的依赖性。
3. 削峰填谷
- 削峰:高并发场景下(如秒杀),将突发请求暂存到消息队列,避免直接冲击后端系统。
- 填谷:消费者按照自身处理能力拉取消息,平滑处理流量峰值,防止系统过载。
二、RocketMQ 核心组件
1. NameServer
- 节点之间互不通信:每个 NameServer 独立保存全量路由信息,无主从选举,无状态,可水平扩展。
- 提供路由注册与发现:Broker 启动时向所有 NameServer 注册,Producer/Consumer 从任意 NameServer 拉取 Topic 对应的 Broker 地址。
- 解耦设计:生产者和消费者只与 NameServer 通信获取路由,不直接感知 Broker 集群变化。
2. Producer(生产者)
- 发送方式
- 同步发送:发送后等待 Broker 返回结果,适合对可靠性要求高的场景(如关键业务通知)。
- 异步发送:发送后提供回调函数,不阻塞主线程,适合对延迟敏感但需要确认结果的场景。
- 单向发送:只发不管结果,性能最高,适合日志收集等可容忍丢失的场景。
3. Broker(服务节点)
- 物理结构:
Broker → Topic → Queue- 每个 Topic 包含多个 Queue(分区),Queue 是消息存储的最小单位,顺序写入。
- CommitLog + ConsumeQueue 机制
- CommitLog:所有消息顺序追加写入磁盘文件,物理存储位置。
- ConsumeQueue:为每个 Queue 建立的逻辑索引,记录消息在 CommitLog 中的偏移量、大小、Tag 哈希码。
- 优势:CommitLog 顺序写性能极高;ConsumeQueue 轻量级,支持快速定位消息。
- 消息类型及实现

==延时消息:会先放到一个专门的Topic里==
==过滤消息:Tag只是给消息打上了标签,其他没有任何变化,消费者消费的时候只会消费符合自己订阅的标签的消息==
==顺序消息:队列都是平均分配给消费者组里的所有实例的,也就是说一个队列只会被一个实例消费,但一个实例可能开多个线程去消费,所以顺序消费需要单线程取消费保证顺序==
4. Consumer(消费者)
订阅模式
- 集群模式(常用):一个消费者组内的多个消费者分摊消费 Topic 下所有 Queue 的消息。一条消息仅被组内一个消费者处理。适合负载均衡。
- 广播模式:一条消息会被消费者组内的所有消费者都消费一遍。适合配置更新、本地缓存刷新等场景。
集群模式:消费进度集中存储在Broker端,由同一个消费者组共享。
广播模式:消费进度存储在每个消费者实例的本地(如本地文件)。各实例之间的消费进度互不影响、互不共享。
消费者组
示例:
- Topic 有 4 个队列(Q1-Q4),消费者组 G 有 2 个实例 C1、C2
- 集群模式:C1 消费 Q1、Q2,C2 消费 Q3、Q4
- 广播模式:C1 和 C2 都消费 Q1-Q4 的全部消息
接收方式
- Push 模式(实际是长轮询 Pull):Consumer 主动向 Broker 发起 Pull 请求,Broker 若无新消息则挂起请求(默认 15s)。看起来像服务端推送,本质是客户端循环拉取。
- Pull 模式:消费者自行控制拉取频率和每次拉取数量,按自身能力消费,避免压力过大。适合批量处理或自定义限流。
幂等性
方案1:数据库唯一约束(最常用)
方案2:Redis原子操作
死信队列
消费者抛出异常或返回 RECONSUME_LATER后,消息进入重试队列,默认16次重试后,会进入死信队列,运维通过控制台人工处理
消息堆积
增加消费者实例
增加消费者线程数量
消费这么慢,消费者的逻辑是不是也该优化下了
可靠性
生产阶段:
同步发送阻塞获取发送结果;
异步发送回调获取发送结果;
==无论哪种发送方式,应该监测发送状态,然后在业务侧做重试==
存储阶段
刷盘策略+主从同步
消费阶段
消费者抛出异常或返回 RECONSUME_LATER后,消息进入重试队列,默认16次重试后,会进入死信队列,运维通过控制台人工处理
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 夏天的风吹向哪里!
