RabbitMQ 基础面试题


RabbitMQ 是什么?核心优势是什么?

RabbitMQ 是基于 AMQP 协议的开源消息队列,主打高可用、易扩展。
核心优势:

  1. 支持多种消息模式(直连、主题、扇形等);
  2. 高可用(集群、镜像队列);
  3. 灵活的路由策略;
  4. 支持消息确认、持久化,保证可靠性。

RabbitMQ 核心组件有哪些?各自作用?

生产者:发消息的应用;
消费者:收消息的应用;
交换机(Exchange):接收生产者消息,根据路由规则转发到队列;
队列(Queue):存储消息,给消费者消费;
绑定(Binding):连接交换机和队列,设置路由规则;
虚拟主机(VHost):隔离不同业务的消息(权限、资源隔离);
连接 / 信道(Connection/Channel):Connection 是 TCP 连接,Channel 是连接内的轻量级通道,减少 TCP 创建开销。

RabbitMQ 有哪些交换机类型?各自场景?

Direct(直连):按精确的 Routing Key 匹配,一对一(比如订单支付通知);
Fanout(扇形):广播,把消息发给所有绑定的队列,无路由规则(比如日志广播);
Topic(主题):按通配符(#/*)匹配 Routing Key,多对多(比如按用户类型推送消息);
Headers:按消息头匹配,很少用(不如 Topic 灵活)。

RabbitMQ 消息发送的基本流程?

  1. 生产者建立 TCP 连接,创建 Channel;
  2. 生产者声明交换机、队列,绑定交换机和队列;
  3. 生产者通过 Channel 发送消息到交换机;
  4. 交换机根据路由规则,把消息转发到对应队列;
  5. 消息持久化(若配置),等待消费者消费。

RabbitMQ 的消息传递流程是怎样的

​生产者发送消息到交换机,交换机根据路由规则(如路由键匹配)将消息转发到对应的队列,​消费者从队列订阅并获取消息

什么是死信队列?应用场景?

死信是指无法被消费的消息(比如过期、被拒、队列满),死信队列就是存储 “死信” 的队列
场景:

  1. 处理消费失败的消息(比如订单超时未支付);
  2. 消息重试失败后归档,方便排查;
  3. 防止无效消息堆积。

什么是延迟队列?怎么实现?

延迟队列是消息延迟指定时间后才被消费的队列(比如订单 15 分钟未支付自动取消)。
实现方式:

  1. 用 RabbitMQ 的延迟插件(推荐,简单);
  2. 结合死信队列 + TTL(消息过期后进入死信队列,实现延迟)。

RabbitMQ 消费模式有哪些?区别是什么?

推模式(Basic.Consume):MQ 主动推消息给消费者,适合高并发(默认);
拉模式(Basic.Get):消费者主动去 MQ 拉消息,适合低并发、按需消费;
核心区别:推模式实时性高,需控制推送速率(避免压垮消费者);拉模式可控性强,但实时性差。

信道(Channel)的作用?为什么不用直接用 Connection?

Channel 是 Connection 内的轻量级通道,共享一个 TCP 连接:

  1. TCP 连接创建开销大(三次握手),Channel 避免频繁创建销毁 TCP;
  2. 每个 Channel 有独立的 ID,可并发操作,兼顾性能和资源占用;
  3. 一个 Connection 可创建多个 Channel,满足多线程消费 / 生产需求。

RabbitMQ 消息的 TTL 是什么?怎么设置?

TTL 是消息的过期时间,超过时间未消费则变为死信。
设置方式:

  1. 队列级别:给队列设 TTL,所有消息都有相同过期时间
  2. 消息级别:发消息时指定 TTL,不同消息可设不同时间;
    注意:消息级别 TTL 优先级高于队列级别。

消息重复消费怎么解决?

核心:让消费逻辑幂等(多次执行结果一致)。
实现方式:

  1. 给消息加唯一 ID(比如订单号),消费前查 Redis/Mongo,已消费则跳过;
  2. 数据库操作加唯一索引,重复插入报错则忽略;
  3. 分布式锁,消费时加锁,避免并发重复消费。

消息堆积怎么解决?

  1. 临时扩容:增加消费者实例,提高消费速度;
  2. 优化消费逻辑:简化业务、异步处理,提高单消费者处理效率;
  3. 分流:把堆积队列的消息转发到多个队列,多消费者并行消费;
  4. 预防:合理设置队列大小、限流,生产端削峰(比如用限流插件)。

如何保证 RabbitMQ 消息不丢失?(核心)

从三个环节保障:

  1. 生产端:开启确认机制(Publisher Confirm),确保消息到交换机;开启返回机制(Publisher Return),确保消息到队列;
  2. 服务端:交换机、队列、消息都开启持久化,防止 MQ 宕机丢失;
  3. 消费端:关闭自动确认,消费成功后手动确认(Basic.Ack),失败则拒绝(Basic.Nack),避免消费一半宕机丢失。

生产端确认机制(Publisher Confirm)怎么用?

  1. 开启确认模式:channel.confirmSelect ();
  2. 同步确认:等待 MQ 返回确认结果,失败则重试;
  3. 异步确认:注册回调函数,收到确认 / 失败通知后处理(推荐,性能高);
    核心:确保消息成功到达 MQ 交换机,失败则重试或记录日志。

消费端手动确认的三种方式?

Basic.Ack:确认消费成功,MQ 删除消息;
Basic.Nack:拒绝消费,可指定是否重新入队(requeue=true);
Basic.Reject:拒绝单条消息,功能和 Nack 类似,但只能拒单条;
注意:失败重试时要设置重试次数,避免无限循环。

如何实现消息重试?

  1. 消费失败时,Basic.Nack (requeue=true) 重新入队(简单,但可能频繁重试);
  2. 结合死信队列:重试 N 次后,消息进入死信队列,人工排查;
  3. 用重试框架:比如 Spring Retry,设置重试次数、间隔,失败后走降级逻辑。

RabbitMQ 如何做限流?

  1. 消费端限流:Basic.Qos (prefetchCount=10),指定消费者最多预取 10 条消息,处理完再取,避免压垮消费者;
  2. 生产端限流:控制发送速率(比如加令牌桶),或用 MQ 的流控机制(避免 MQ 堆积)。

如何实现消息的顺序消费?

  1. 单队列 + 单消费者:简单但并发低;
  2. 分区队列:按顺序关键字(比如订单 ID 哈希)发送到固定队列,每个队列一个消费者,保证同关键字消息顺序消费;
    注意:必须保证生产者发送顺序、队列存储顺序、消费者消费顺序一致。

RabbitMQ 如何实现事务消息?

RabbitMQ 本身不支持事务消息,用 “本地消息表 + 重试” 实现最终一致性:
① 生产端:先写本地消息表(状态待发送),再发 MQ 消息;
② 收到 MQ 确认后,更新消息表为已发送;
③ 定时扫描本地消息表,重发未确认的消息;
④ 消费端:消费成功后,通知生产端更新状态,失败则重试。

RabbitMQ 监控重点看哪些指标?

① 队列指标:消息堆积数、入队 / 出队速率;
② 连接 / 信道:活跃连接数、信道数(避免过多);
③ 消费者指标:消费速率、未确认消息数;
④ 节点指标:CPU、内存、磁盘使用率(避免磁盘满导致 MQ 不可用)。

消息发送成功但消费者收不到,怎么排查?

① 查交换机和队列是否绑定,路由 Key 是否匹配;
② 查消息是否过期(TTL),是否变成死信;
③ 查消费者是否正常运行,是否开启手动确认但未 Ack;
④ 查 MQ 日志,看是否有转发失败、权限不足的报错。

RabbitMQ 节点宕机怎么处理?

① 有镜像队列:故障节点的队列自动切换到其他节点,无数据丢失,消费者重新连接即可;
② 无镜像队列:重启节点,恢复数据(若开启持久化),或从备份恢复;
③ 预防:配置镜像队列、集群,定期备份数据。

消费端阻塞怎么排查?

① 查消费者日志,看是否有死循环、慢 SQL、远程调用超时;
② 查 MQ 的未确认消息数,若持续增加,说明消费阻塞;
③ 重启消费者实例,临时恢复,再优化消费逻辑。

RabbitMQ 集群原理?为什么需要镜像队列?

集群原理:节点之间同步元数据(交换机、队列结构),不同节点存储不同队列的数据,实现负载分担;
镜像队列:把队列复制到多个节点,解决单节点故障导致队列数据丢失的问题,保证高可用(生产必配)。

RabbitMQ 常用交换机?项目用了哪种?
答:Direct/Topic/Fanout/Headers;航天云膜用 Topic 模式做库存变更通知,通配符匹配不同仓库队列。

  • 在你们的项目中, Rabbit MQ 的具体配置和优化措施有哪些?比如预取值持久化策略等。
    在项目中,RabbitMQ 预取值设为 50,避免消费者一次性拉取过多消息导致堆积。持久化策略方面,消息设置 deliveryMode=2,队列和交换机也开启持久化,确保服务重启后消息不丢失。还优化了消费者线程池,核心线程数设为 CPU 核心数2,最大线程数4,和 XML 解析线程池保持一致,避免资源竞争。另外,给队列设置了死信交换机,超时未处理的消息自动进入死信队列,防止消息积压。

在项目中如何使用消息队列的,我这块用RabbitMQ用的比较多

在最近的项目中没用到,我记得在其它项目中使用过
比如在库存管理系统,使用的是Topic模式
在application配置文件中配置rabbitmq,然后在项目中创建配置类定义 Exchange 和 Queue;
​实现方式:
当商品库存发生变更时,通过预定义的 Topic(如 inventory.update)发送消息至订阅节点,触发实时刷新

关键点是 rabbitTemplate要设置两个回调
确认消息已到达时触发
消息无法路由时触发

RabbitMQ和RocketMQ区别

RabbitMQ 适合 ​灵活路由、轻量级异步场景​(如微服务解耦)。
RocketMQ 适合 ​高并发、海量消息、复杂业务流​(如电商秒杀、日志流处理)。


文章作者: zrh
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 zrh !
  目录