Skip to content

09 - RabbitMQ 面试高频题汇总

定位:大厂 Java 面试 · RabbitMQ 速查手册 使用方式:面试前快速过一遍,每个问题附带 15 秒标准答案


🔥 TOP 10 必问题

Q1:RabbitMQ 的核心组件有哪些?

Producer(生产者)→ Exchange(交换机)→ Binding(绑定)→ Queue(队列)→ Consumer(消费者)。消息不直接发到 Queue,而是发到 Exchange,由 Exchange 根据 RoutingKey 和 BindingKey 的匹配关系路由到对应的 Queue。

Q2:RabbitMQ 有哪些 Exchange 类型?各自特点?

类型路由规则场景
DirectRoutingKey 完全匹配精确路由
Fanout广播到所有绑定队列日志广播
Topic* 匹配一个词,# 匹配多个词多维分类
Headers按 Header 属性匹配灵活路由

Q3:如何保证消息不丢失?

三个环节三重保障

  1. 生产端:开启 Confirm 模式(异步)+ mandatory + Return 回调
  2. Broker 端:Exchange + Queue + Message 三重持久化 + 镜像/仲裁队列
  3. 消费端:手动 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-delay header,精确延迟。 方案三:Redis ZSET + 时间轮询。

Q7:如何保证消息幂等性(不重复消费)?

RabbitMQ 只保证 At-Least-Once,不保证 Exactly-Once。幂等方案:

  1. Redis SETNX:消息 ID 去重(高并发推荐)
  2. 数据库唯一约束:message_id 唯一索引(兜底)
  3. 状态机:只允许合法状态转移(订单类推荐) 生产推荐:Redis 去重 + 状态机 + DB 唯一约束 三层防护

Q8:消息积压怎么处理?

紧急处理

  1. 快速扩容消费者 Pod(3 → 30)
  2. 修复消费端 Bug
  3. 新建临时队列分流(转移消费者 + 多消费者组) 长期优化
  • 提高并发(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 重试?

yaml
spring.rabbitmq.listener.simple.retry:
  enabled: true
  initial-interval: 3000
  multiplier: 2.0
  max-attempts: 3
  max-interval: 10000

注意:Spring 重试在应用层重试,不涉及 Broker 重新投递。超过次数后可以配置 RejectAndDontRequeueRecoverer 发送到 DLX。

Q20:消费者处理太慢怎么办?

  1. 增加 concurrency(消费者并发数)
  2. 增加消费者实例
  3. 批量消费(batchSize
  4. 优化消费逻辑(异步化、批量 DB、缓存)
  5. 适当增大 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**

Knowledge4J — Java 知识库