消息中间件(MQ)
案例必考:三大作用 + 两种模式 + 可靠投递 + 幂等
一、MQ 的三大核心作用 ⭐⭐⭐
① 异步解耦
生产者无需等待消费者,降低系统间依赖,允许独立演进。
② 流量削峰
突发流量先入队列,消费者按自己节奏处理,保护下游。
③ 异步通信 / 提速
主流程只发消息即可返回,大幅提高响应速度。
口诀:"解耦 · 削峰 · 异步" 3 大场景
二、两种消息模型
1. 点对点 P2P (Queue)
生产者 → [队列] → 消费者(只有一个消费)
每条消息只有一个消费者消费,典型:任务分发。
2. 发布订阅 Pub/Sub (Topic)
生产者 → [Topic] → 多个订阅者(每个都收到)
每条消息广播给所有订阅者,典型:事件通知。
三、可靠性三段保证(必背)⭐⭐⭐
从生产者 → MQ → 消费者全链路保证消息不丢失:
- 生产端: 同步发送 + 确认机制(ACK) + 失败重试 + 本地消息表/事务消息
- MQ Broker 端: 持久化(磁盘) + 主从复制 + 集群高可用
- 消费端: 手动 ACK,业务完成后再确认;失败重试 + 死信队列(DLQ)
口诀:"生·存·消" 三段保可靠
四、消息幂等(必考)
MQ 至少保证 at-least-once(至少一次)送达,所以消费端 必须幂等,避免重复消费。
实现方式:
- 唯一 ID / 全局 ID + DB 唯一索引
- Redis SetNX 锁 记已处理 ID
- 状态机校验(订单状态只能向前推进)
- Token 令牌:幂等令牌一次性使用
- 乐观锁(版本号)
五、4 大主流 MQ 对比 ⭐⭐
| Kafka | RocketMQ | RabbitMQ | ActiveMQ | |
|---|---|---|---|---|
| 语言 | Scala/Java | Java | Erlang | Java |
| 吞吐 | 百万 TPS | 十万级 | 万级 | 万级 |
| 延迟 | 毫秒级 | 毫秒级 | 微秒级 | 毫秒级 |
| 顺序消息 | 分区有序 | 支持 | 队列有序 | 较弱 |
| 事务 | 较弱 | 支持 | 支持 | 支持 |
| 典型场景 | 大数据日志、流处理 | 电商订单、金融 | 企业内传统业务 | 遗留系统 |
六、典型场景 & 答题套路
题型:为什么订单系统要引入 MQ?
- 解耦:订单、库存、积分、通知拆分,任意一方升级互不影响
- 削峰:秒杀场景流量先入队,后端消费者按能力处理
- 异步:主链路只保证下单,周边业务异步执行,响应从 800ms → 100ms
- 最终一致:配合本地消息表,实现跨服务事务
题型:如何保证消息不丢失?
"采用 三段式保证:
① 生产端:同步发送 + ACK 确认 + 失败重试 + 本地消息表;
② Broker:开启持久化、副本机制、ACK ALL;
③ 消费端:手动 ACK,业务成功才提交;消费失败进入死信队列人工干预。"
题型:如何处理消息重复消费?
"MQ 至少一次投递,业务端必须保证 幂等。常用方法:① 全局唯一 ID + DB 唯一索引;② Redis 记已处理标记;③ 状态机限制 + 乐观锁。"
✅ 自测
1. MQ 的三大作用?
2. 如何保证消息不丢?三个环节各自做什么?
3. 消费端幂等三种实现?
4. Kafka 与 RocketMQ 各自适合什么场景?
📗 高频专题 · MQ 完