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(MessageID)。消费前先去 Redis 查一下这个 ID 是否存在。如果存在,说明消费过了;如果不存在,则执行业务并把 ID 存入 Redis。

  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)。"

相关推荐
可爱又迷人的反派角色“yang”6 小时前
zookeeper概念与部署
分布式·zookeeper·云原生
努力学算法的蒟蒻6 小时前
day34(12.15)——leetcode面试经典150
算法·leetcode·面试
✿ ༺ ོIT技术༻6 小时前
服务端高并发分布式结构演进之路
运维·服务器·redis·分布式·架构
码界奇点6 小时前
基于Spring Cloud Alibaba的分布式微服务权限管理系统设计与实现
分布式·spring cloud·微服务·架构·毕业设计·源代码管理
vx_bisheyuange6 小时前
基于SpringBoot的失物招领平台的设计与实现
java·spring boot·后端·毕业设计
Query*7 小时前
分布式消息队列kafka【四】—— 消费者进阶提升
分布式·kafka·linq
Query*7 小时前
分布式消息队列kafka【三】—— 生产者进阶提升
分布式·kafka·linq
风跟我说过她7 小时前
基于Scrapy-Redis的分布式房产数据爬虫系统设计与实现
redis·分布式·爬虫·scrapy
ByNotD0g7 小时前
Go 泛型 in 1.25
开发语言·后端·golang