消息队列基础概念
学习消息队列的基础概念、核心模型和 Kafka/RocketMQ/RabbitMQ 三大主流 MQ 对比
消息队列基础概念
什么是消息队列
消息队列(Message Queue)是一种异步通信中间件。生产者把消息发到队列,消费者从队列取消息处理——两者不直接通信,解耦了时间和空间。
┌──────────┐ ┌──────────────┐ ┌──────────┐
│ Producer │ ───▶ │ Message Queue │ ───▶ │ Consumer │
│ (发送方) │ │ (Broker) │ │ (消费方) │
└──────────┘ └──────────────┘ └──────────┘
特点:生产者发完就完事,不用等消费者处理;
消费者按自己的节奏消费,生产者不知道谁在消费。
为什么需要消息队列
| 目的 | 场景 | 没有 MQ 时 | 有 MQ 后 |
|---|---|---|---|
| 削峰填谷 | 秒杀/抢购 | 瞬间流量打崩后端 | MQ 缓冲,后端匀速消费 |
| 异步解耦 | 订单→扣库存→发短信→记日志 | 同步调用链,任一环节慢则整体慢 | 订单发一条消息,各系统各自消费 |
| 系统解耦 | 微服务间通信 | A 调 B 的 API,B 挂了 A 也挂 | A 发消息,B 恢复后再消费 |
| 日志收集 | 应用日志→Kafka→ELK | 日志写磁盘,影响业务性能 | 异步发送,按批次落盘 |
| 事件驱动 | CQRS / Event Sourcing | 数据库直接读写,无法回溯 | 事件流可重放、可审计 |
两种核心模型
队列模型(点对点)
Producer → [Queue] → Consumer
↑
一条消息只能被一个消费者处理一次
发布-订阅模型(Pub/Sub)
┌──→ Consumer A
Producer → [Topic] ─┼──→ Consumer B
└──→ Consumer C
↑
一条消息可以被多个消费者各自处理
Kafka 和 RocketMQ 都基于 Pub/Sub 模型,把消息按 Topic 分类,每个 Topic 可以有多个消费者组。
核心概念速查
| 概念 | Kafka 术语 | RocketMQ 术语 | 说明 |
|---|---|---|---|
| 消息分类 | Topic | Topic | 消息的逻辑分类,类似数据库的表 |
| 分区 | Partition | MessageQueue | Topic 内的物理分片,并行读写 |
| 生产者 | Producer | Producer | 发送消息的一方 |
| 消费者 | Consumer | Consumer | 接收处理消息的一方 |
| 消费者组 | Consumer Group | Consumer Group | 组内负载均衡,组间广播 |
| 偏移量 | Offset | Offset | 消费进度标记位 |
| Broker | Broker | Broker | 消息与流处理进程 |
| 副本 | Replica | — | 数据冗余备份 |
消息可靠性语义(Delivery Semantics)
| 级别 | 含义 | 如何实现 |
|---|---|---|
| At-most-once | 最多一次,可能丢 | 发完不管,不确认 |
| At-least-once | 至少一次,可能重复 | 消费者确认后提交 offset(默认) |
| Exactly-once | 精确一次 | 事务消息 + 幂等消费 |
生产环境默认是 At-least-once,业务方需要自己做幂等(重复消费处理)。
三种主流 MQ 对比
| 维度 | Kafka | RocketMQ | RabbitMQ |
|---|---|---|---|
| 开发语言 | Java/Scala | Java | Erlang |
| 吞吐量 | 百万级 msg/s | 十万级 msg/s | 万级 msg/s |
| 延迟 | 毫秒级 | 毫秒级 | 微秒级(低负载) |
| 消息可靠性 | 高(ISR 机制) | 高(同步刷盘) | 高(持久化+确认) |
| 顺序消息 | 分区内有序 | 队列内有序 | 队列内有序 |
| 延迟消息 | ❌ 不原生支持 | ✅ 18 个延迟级别 | ✅ 死信+TTL 变通 |
| 运维复杂度 | 中(需 ZK/KRaft) | 中(NameServer) | 低(单节点即可) |
| 生态 | 最大(大数据标配) | 阿里开源,国内流行 | 协议标准(AMQP) |
选型速记
需要超大数据吞吐(日志/埋点/流计算)→ Kafka
需要事务消息 + 延迟消息(订单/支付)→ RocketMQ
需要标准协议 + 灵活路由 + 低运维成本 → RabbitMQ
消费模式
Push vs Pull
| 模式 | 说明 | 代表 |
|---|---|---|
| Push | Broker 主动推给消费者 | RabbitMQ(默认) |
| Pull | 消费者主动拉取(长轮询) | Kafka、RocketMQ |
Pull 的优势:消费者按自己的处理能力拉取,不会被打垮。
消费者组再均衡(Rebalance)
Consumer Group: [C1, C2, C3] → 消费 Topic T(3 个 Partition)
正常状态:C1→P0, C2→P1, C3→P2
C2 挂了 → C1→P0+P1, C3→P2 ← 自动重分配
C2 恢复 → C1→P0, C2→P1, C3→P2 ← 重新均衡
再均衡期间,该消费者组暂停消费(Stop-The-World),所以要避免频繁发生。
常见问题速查
| 问题 | 原因 | 影响 |
|---|---|---|
| 消息积压 | 消费速度 < 生产速度 | 延迟增大,最终可能撑爆磁盘 |
| 重复消费 | 网络超时重试 / Rebalance | 业务数据重复(需幂等) |
| 消息丢失 | Producer ack=0 / Broker 未刷盘 | 数据不一致 |
| 顺序错乱 | 重试消息插队 | 先下单后取消可能变成先取消后下单 |
自检清单
- 能用自己的话解释「消息队列解决什么问题」
- 能画出 Pub/Sub 模型并说明和点对点的区别
- 能区分 At-least-once / At-most-once / Exactly-once
- 能说出 Kafka/RocketMQ/RabbitMQ 各适合什么场景
- 理解 Partition / Consumer Group / Rebalance 的关系
- 知道消息积压、重复消费、消息丢失的原因