09 - RabbitMQ 面试高频题汇总
定位:大厂 Java 面试 · RabbitMQ 速查手册 使用方式:面试前快速过一遍,每个问题附带 15 秒标准答案
🔥 TOP 10 必问题
Q1:RabbitMQ 的核心组件有哪些?
Producer(生产者)→ Exchange(交换机)→ Binding(绑定)→ Queue(队列)→ Consumer(消费者)。消息不直接发到 Queue,而是发到 Exchange,由 Exchange 根据 RoutingKey 和 BindingKey 的匹配关系路由到对应的 Queue。
Q2:RabbitMQ 有哪些 Exchange 类型?各自特点?
| 类型 | 路由规则 | 场景 |
|---|---|---|
| Direct | RoutingKey 完全匹配 | 精确路由 |
| Fanout | 广播到所有绑定队列 | 日志广播 |
| Topic | * 匹配一个词,# 匹配多个词 | 多维分类 |
| Headers | 按 Header 属性匹配 | 灵活路由 |
Q3:如何保证消息不丢失?
三个环节三重保障:
- 生产端:开启 Confirm 模式(异步)+ mandatory + Return 回调
- Broker 端:Exchange + Queue + Message 三重持久化 + 镜像/仲裁队列
- 消费端:手动 ACK,先处理业务后确认
Q4:Confirm 模式和事务的区别?
- 事务:同步阻塞,吞吐量下降 10 倍+,
txSelect/txCommit- Confirm:异步批量确认,高性能,
confirmSelect+ 回调监听- 生产环境只用 Confirm,不用事务
Q5:什么是死信队列?什么场景用?
消息变成"死信"的三种情况:① 被 reject/nack 且 requeue=false ② TTL 过期 ③ 队列满(x-max-length)。死信会被路由到 DLX(死信交换机)→ DLQ(死信队列)。场景:消费失败兜底、实现延迟队列、异常消息人工处理。
Q6:如何实现延迟队列?
方案一(TTL + DLX):消息发到设置 TTL 的队列,过期后进入死信队列处理。缺点:消息 TTL 排队问题导致不精确。 方案二(延迟插件,推荐):安装
rabbitmq_delayed_message_exchange插件,发送时设置x-delayheader,精确延迟。 方案三:Redis ZSET + 时间轮询。
Q7:如何保证消息幂等性(不重复消费)?
RabbitMQ 只保证 At-Least-Once,不保证 Exactly-Once。幂等方案:
- Redis SETNX:消息 ID 去重(高并发推荐)
- 数据库唯一约束:message_id 唯一索引(兜底)
- 状态机:只允许合法状态转移(订单类推荐) 生产推荐:Redis 去重 + 状态机 + DB 唯一约束 三层防护
Q8:消息积压怎么处理?
紧急处理:
- 快速扩容消费者 Pod(3 → 30)
- 修复消费端 Bug
- 新建临时队列分流(转移消费者 + 多消费者组) 长期优化:
- 提高并发(concurrency + 批量消费)
- 优化消费逻辑(批量 DB、异步化、缓存)
- 队列长度限制 + 死信兜底
Q9:仲裁队列和镜像队列的区别?
| 维度 | 镜像队列 | 仲裁队列 |
|---|---|---|
| 协议 | 主从复制 | Raft 共识 |
| 一致性 | 最终一致 | 强一致 |
| 故障转移 | 秒级(最老 Slave) | 秒级(Leader 选举) |
| 版本 | 3.8 之前推荐 | 3.8+ 推荐 |
| 状态 | 已废弃 | ✅ 官方推荐 |
Q10:为什么选择 RabbitMQ 而不是 Kafka?
- RabbitMQ:延迟低(微秒级)、消息可靠(confirm+持久化+ACK)、路由灵活(Exchange)、适合业务消息
- Kafka:吞吐量大(百万级/s)、适合日志收集和大数据流
- 如果需要复杂路由 + 消息可靠性 + 低延迟 → RabbitMQ
- 如果需要高吞吐 + 日志采集 + 流处理 → Kafka
⭐ 进阶高频题
Q11:Channel 和 Connection 的关系?
Connection 是 TCP 长连接,Channel 是复用 Connection 的虚拟连接。创建 TCP 连接成本高,所以一个应用创建少量 Connection,用多个 Channel 处理并发。Channel 不是线程安全的,每个线程应持有独立 Channel。
Q12:RabbitMQ 消息有大小限制吗?
默认最大 128MB,但生产建议 < 1MB。大消息处理方式:① 压缩后发送 ② 消息体只存 URL,附件放 OSS ③ 消息分割
Q13:如何保证消息顺序性?
- 单 Queue 单 Consumer:天然有序
- 多 Consumer 无法保证
- 解决方案:同一业务 key 路由到同一队列(hash routing_key),Consumer 端按 key 排序
Q14:什么是 Prefetch?怎么设置?
basicQos(N)设置预取数量:一次从 Broker 取 N 条未 ACK 的消息。
prefetch=1:严格顺序,逐条消费(订单状态)prefetch=10-50:批量消费,高吞吐(日志处理)prefetch=0:不限制(不推荐,易 OOM)
Q15:如何实现重试 N 次后进入死信队列?
消费端维护重试计数(存 Header
x-retry-count),每次失败 +1。达到阈值后basicNack(tag, false, false)(requeue=false),消息进入 DLX。未达阈值则重新发送到队列并更新计数。
Q16:RabbitMQ 的内存告警和磁盘告警?
当内存使用超过阈值(默认 40%)或磁盘剩余空间不足时,RabbitMQ 会阻塞所有生产者(flow control),直到资源恢复正常。这是 Broker 的自我保护机制。
Q17:vhost 的作用?
Virtual Host 提供逻辑隔离:不同业务使用不同 vhost,拥有独立的 Exchange/Queue/权限。一套集群服务多套业务(多租户),互不干扰。
Q18:什么是 Alternate Exchange?
声明 Exchange 时设置
alternate-exchange参数,当消息无法路由到任何 Queue 时,自动转发到备用交换机。类似兜底策略,确保消息不丢失。
Q19:SpringBoot 中如何配置 RabbitMQ 重试?
yamlspring.rabbitmq.listener.simple.retry: enabled: true initial-interval: 3000 multiplier: 2.0 max-attempts: 3 max-interval: 10000注意:Spring 重试在应用层重试,不涉及 Broker 重新投递。超过次数后可以配置
RejectAndDontRequeueRecoverer发送到 DLX。
Q20:消费者处理太慢怎么办?
- 增加
concurrency(消费者并发数)- 增加消费者实例
- 批量消费(
batchSize)- 优化消费逻辑(异步化、批量 DB、缓存)
- 适当增大 prefetch
💡 方案设计题
Q21:设计一个订单超时自动关闭系统
方案:延迟队列
1. 创建订单时发送延迟消息(TTL=30min)
2. 30min 后消息过期进入死信队列
3. 死信消费者检查订单状态:
- 未支付 → 关闭订单 + 释放库存
- 已支付 → 忽略
优化:使用延迟插件(x-delayed-message)替代 TTL+DLX
幂等:Redis 检查订单 ID 防止重复关闭Q22:设计一个分布式消息最终一致性方案
1. 本地消息表:业务操作 + 消息记录在同一事务写入 DB
2. 定时任务扫描本地消息表,发送到 MQ
3. 消费端:幂等消费 + 手动 ACK
4. ACK 成功后更新消息状态为"已消费"
5. 超时未消费的消息告警 + 人工介入
关键:本地事务保证业务和消息的一致性Q23:如何实现消息的广播 + 个性化消费?
Fanout Exchange + 临时队列
1. Fanout 广播到所有绑定队列
2. 每个服务创建独占队列(exclusive=true 或 持久化独立队列)
3. 各服务独立消费,互不影响
示例:用户注册后广播 → 短信服务 + 邮件服务 + 积分服务📌 面试答题框架
遇到任何 MQ 题,按这个框架回答:
1. 是什么 → 定义/概念
2. 为什么 → 为什么需要(解决什么问题)
3. 怎么做 → 具体实现方案
4. 有什么坑 → 注意事项 / 踩坑经验
5. 你们怎么用 → 结合项目经验(最重要!)加分项:
- 能说出具体数值(prefetch=10、TTL=30min、3 节点仲裁队列)
- 能对比多种方案的优劣
- 能结合实际项目说明选型理由
- 能说出踩过的坑和解决方案
🔗 快速跳转
| 需要深入了解? | 跳转链接 |
|---|---|
| AMQP 基础 | **RabbitMQ基础与核心概念** |
| Exchange 对比 | **交换机类型与路由策略** |
| 消息可靠性 | **消息可靠性保障** |
| 死信/延迟队列 | **死信队列与延迟队列** |
| 幂等设计 | **消息幂等性与重复消费** |
| 消息积压 | **消息积压与消费能力** |
| 集群高可用 | **集群与高可用架构** |
| SpringBoot 整合 | **SpringBoot整合RabbitMQ** |