详细介绍:RabbitMQ面试题(不定时更新)

可以参考之前的rabbitmq的全部内容博客rabbitmq


1. 介绍一下 RabbitMQ 的核心组件和工作原理

知识点解析:

想象成寄快递:

  • Producer(生产者): 寄件人。

  • Exchange(交换机):快递分拣中心。它不存快递,只负责按地址(Routing Key)分发。

  • Queue(队列):具体的快递站点/仓库。快递存在这里。

  • Binding(绑定):分拣中心到站点的卡车路线。

  • Consumer(消费者): 收件人。

️ 面试参考回答:

“RabbitMQ 的工作模型是基于 AMQP 协议的。它的核心组件首要包括:

  1. Producer(生产者):发送消息的应用。

  2. Consumer(消费者):接收和处理消息的应用。

  3. Exchange(交换机):接收生产者发送的消息,并根据路由键(Routing Key)将消息路由到绑定的队列中。它本身不存储消息

  4. Queue(队列):存储消息的容器,消息在这里等待被消费。

工作原理是:

生产者将消息发送给交换机,交换机根据Routing Key(路由键)和Binding(绑定关系),将消息转发到具体的Queue(队列)。消费者监听队列,从队列中获取消息进行消费。”


2. 交换机 (Exchange) 有哪些类型?

知识点解析:

分拣中心的策略:

  • Fanout:广播。不管地址,所有连我的站点都给一份。

  • Direct:直连。地址必须完全匹配。

  • Topic: 主题。地址可以模糊匹配(比如 *.news)。

  • Headers:看信封属性(不常用)。

️ 面试参考回答:

“RabbitMQ 常用的交换机类型有四种:

  1. Direct Exchange(直连交换机):路由键完全匹配。消息的 Routing Key 必须和 Binding Key 完全一致才会被转发,常用于点对点通信

  2. Fanout Exchange(广播交换机):忽略路由键,将消息广播到所有绑定到该交换机的队列。速度最快。

  3. Topic Exchange(主题交换机): 支持通配符匹配。Routing Key 行包含*(匹配一个单词)和 #(匹配零个多个单词),非常灵活。

  4. Headers Exchange: 根据消息头的属性路由键。在实际开发中用得比较少。”就是进行匹配,而不


3. RabbitMQ 中有哪些消息模型?

知识点解析:

通常指 RabbitMQ 官方教程提到的 5 种模式:

  1. 简单队列(一对一)。

  2. 工作队列(多个人干活,轮流分发)。

  3. 发布订阅(广播,Fanout)。

  4. 路由模式(Direct)。

  5. 主题模式(Topic)。

️ 面试参考回答:

“RabbitMQ 给出了多种消息模型,最常用的包括:

  1. 基本消息模型 (Hello World):一个生产者对应一个队列一个消费者

  2. 工作队列模型 (Work Queues):一个队列绑定多个消费者,消息在消费者之间轮询分发(或者通过能者多劳模式公平分发),用于处理耗时任务。

  3. 发布/订阅模型 (Publish/Subscribe):使用 Fanout(广播)交换机,将消息广播给所有绑定的队列

  4. 路由模型 (Routing):利用 Direct(直接) 交换机,根据路由键有选择地将消息发给特定队列。

  5. 主题模型 (Topics):启用 Topic (主题)交换机,借助通配符进行更灵活的路由。”


4. RabbitMQ 如何确保消息的可靠性?

知识点解析:

消息不能丢,得全链路保障:

  • 发的时候:生产者要确认 MQ 收到了(Confirm/Return 机制)。

  • 存的时候:MQ 自己挂了怎么办?(持久化)。

  • 收的时候:消费者处理失败了怎么办?(手动 Ack)。

️ 面试参考回答:

“消息可靠性需要从发送端、MQ 服务端、消费端三个维度来保证:

  1. 发送端可靠性: 开启 ConfirmCallback(发布确认)和ReturnCallback(回退模式)。确保消息成功到达交换机,且被路由到了队列。如果失败,可以进行重试或记录日志。

  2. 服务端可靠性: 开启持久化。包括 Exchange 持久化、Queue 持久化和 Message 持久化(deliveryMode=2),防止 MQ 重启导致数据丢失。

  3. 消费端可靠性: 使用 手动 ACK 机制(basicAck)。只有当业务逻辑执行成功后,才告诉 MQ 删除消息。如果执行失败,能够拒绝消息(basicNack)并让其重新入队,或者进入死信队列。”


5. RabbitMQ 如何保证消息的幂等性?

知识点解析:

和微服务篇的接口幂等性一样。MQ 重复消费是必然会发生的(比如网络抖动导致 Ack 丢失),于是消费者必须能处理重复消息。

核心:判重

️ 面试参考回答:

“MQ 的重复消费是不可避免的(例如网络波动导致 ACK 丢失),因此必须在消费者端保证幂等性。常见的方案有:

  1. 利用 Redis 原子性:每条消息在生产时生成一个全局唯一的 ID否存在。如果存在,说明消费过了;如果不存在,则执行业务并把 ID 存入 Redis。就是(MessageID)。消费前先去 Redis 查一下该 ID

  2. 数据库唯一索引:如果业务是写数据库,可以利用数据库的主键或唯一约束。重复插入会抛出异常,捕获异常忽略即可。

  3. 乐观锁:若是是更新操作,可以带上版本号条件。”


6. 什么是死信队列?消息是如何成为死信的?

知识点解析:

死信 = “没人要”或“处理不了”的消息。

MQ 只有死信交换机 (DLX),没有专门的死信队列。绑定到 DLX 的队列就叫死信队列。

来源:

  1. 被拒收了(reject)且不让重发(requeue=false)。

  2. 过期了(TTL)。

  3. 队列满了(Max length)。

️ 面试参考回答:

“死信队列是指用来存放那些无法被正常消费的消息的队列。

消息成为‘死信’(Dead Letter)通常有三种情况:

  1. 消息被拒绝: 消费者使用 basic.rejectbasic.nack 拒绝消息,并且设置 requeue=false(不再重新入队)。

  2. 消息过期:消息设置了 TTL(Time To Live),在规定时间内没有被消费。

  3. 队列达到最大长度:队列的消息数量超过了最大限制,最早的消息会被挤掉成为死信。

通常我们会给队列绑定一个死信交换机(DLX),当消息变成死信时,会自动转发到这个交换机,进而进入死信队列,用于后续的人工排查或重试。”


7. 什么是延迟队列?RabbitMQ 如何实现延迟队列?

知识点解析:

场景: 下单 30 分钟不支付自动取消。

RabbitMQ 原生不支持延迟队列(不像 Java DelayQueue)。

野路子实现: 消息设置过期时间 (TTL) + 死信队列 (DLQ)。消息死了以后才会被消费者看到。

正规路子: 安装插件 rabbitmq_delayed_message_exchange。

️ 面试参考回答:

延迟队列是指消息发送后,消费者不会立刻收到,而是等待指定时间后才能消费。常用于‘订单超时取消’等场景。

RabbitMQ 实现延迟队列主要有两种方案:

  1. TTL + 死信队列(最常用): 创建一个没有消费者的 TTL 队列(设置过期时间),并绑定死信交换机。消息发进去后,过期变成死信,被转发到死信队列,消费者监听死信队列,从而实现延迟效果。

  2. 使用延迟插件: 安装 rabbitmq_delayed_message_exchange插件。它允许交换机暂存消息,等到时间到了再投递给队列。这种方式更便捷,不需要创建死信队列。”


8. 如何消除 RabbitMQ 的消息堆积困难?

知识点解析:

池子里的水快溢出来了。

原因: 生产太快,消费太慢(或者消费者挂了)。

解决:

  1. 赶紧修:修复消费者 Bug。

  2. 加人手:多开几个消费者进程。

  3. 临时扩容(大招):原消费者只负责转发,转发到新的临时 Topic,那边开 10 倍的消费者慢慢处理。

️ 面试参考回答:

“消息堆积通常是因为消费者处理速度跟不上生产者发送速度。解决方案如下:

  1. 增加消费者数量:在服务器允许的范围内,增加Consumer 实例线程数,提高并发消费能力。

  2. 优化消费逻辑:检查消费者代码,是否有耗时操作(如慢 SQL、第三方接口),尽量异步处理或优化性能。

  3. 临时扩容(紧急方案):如果堆积非常严重,原来的消费者处理不过来,可以修改消费者应用,将消息快速转发到一个新的、拥有几十个分区的临时 Topic/Queue 中,随后临时启动几十个消费者去专门处理这些积压消息。”


9. RabbitMQ 的集群方案有哪些?

知识点解析:

  1. 普通集群:大家只同步“目录”(元数据),不同步“文件”(消息)。A 节点挂了,B 节点只有目录,没法给用户数据。

  2. 镜像集群(Mirror Queue):真正的 HA(高可用)。数据在节点间同步复制。A 挂了 B 能顶上。

️ 面试参考回答:

“RabbitMQ 常用的集群模式主要有两种:

  1. 普通集群模式:默认模式。所有节点同步交换机、队列的元数据(结构),但消息实体只存储创建队列的那个节点上。假如该节点宕机,消息将不可用。它主要用于提高吞吐量,不能保证高可用。(仅同步元资料,不备份消息,用于提高吞吐量,无高可用。)

  2. 镜像队列模式(Mirror Queue):这是实现**高可用(HA)**的方案。配置策略将队列的消息在多个节点之间进行同步复制(主从结构)。如果 Master 节点挂了,会自动选举一个 Slave 接管。生产环境一般都使用这种模式。”目前在最新版中已被标记为废弃

  3. 仲裁队列(新版 HA): 这是目前生产环境的首选,用于替代镜像队列的。它是基于 Raft 一致性算法完成的。与镜像队列不同,它不需所有节点都同步数据,只要超过半数(Quorum)的节点写入成功即可。它在保证数据安全的同时,大幅克服了旧版镜像队列在网络波动时的性能问题。”


10. RabbitMQ 和 Kafka 的区别?

知识点解析:

  • RabbitMQ:精致的跑车。快,效果多(路由、重试、顺序),可靠性高,但装得少(吞吐量一般,堆积千万级性能下降)。

  • Kafka:大货车。装得多(吞吐量极高,百万级),不仅能跑还能存(日志存储),但功能相对粗糙(以前没有事务、延迟队列等)。

️ 面试参考回答:

“它们侧重点不同,选型依据如下:

  1. 吞吐量:Kafka 设计初衷是处理日志,吞吐量极高(百万级/秒);RabbitMQ 吞吐量较低(万级/秒)。

  2. 可靠性与功能:RabbitMQ 拥护复杂的路由逻辑、死信、延迟队列等,消息可靠性更好,适合业务逻辑复杂、一致性要求高的场景(如订单、支付)。Kafka 适合大数据量、流式计算、日志采集等场景。

  3. 架构模式:RabbitMQ 是基于(Push)模式(也有拉);Kafka 是基于(Pull)模式,只管存,消费者记录消费进度(Offset)。”

posted @ 2026-01-21 19:04  clnchanpin  阅读(3)  评论(0)    收藏  举报