rabbitmq 面试题

一、基础概念

  1. 什么是 RabbitMQ?
  • 基于 AMQP 协议的开源消息中间件,用于实现系统间的异步通信和解耦,支持多种消息模式(如发布/订阅、路由、主题等)。
  1. 你了解那个rabbitmq, rabbitmq 的 虚拟机是啥?

‌****RabbitMQ的虚拟主机(Vhost)主要用于提供逻辑上的隔离,使得在同一RabbitMQ实例上可以运行多个完全隔离的环境‌。这种隔离性对于资源管理、权限控制和多租户架构等方面至关重要‌1。

具体作用和好处

  1. 隔离性‌:Vhost提供了隔离性,使得一个Vhost内的消息、队列和交换机等资源对于其他Vhost来说是不可见和不可访问的。这对于多用户或多项目场景尤其重要,可以避免不同项目之间的相互干扰‌1。
  2. 管理性‌:每个Vhost可以有独立的权限控制,这使得对不同项目或团队的管理变得简单,简化了管理工作‌1。
  3. 安全性‌:Vhost的隔离和权限控制增强了系统的安全性,即使是在相同的物理服务器上,不同Vhost之间的操作也不会相互影响‌1。

具体应用场景

多租户架构中,每个租户可以拥有自己的Vhost,从而确保数据和资源的隔离。此外,在大型组织中,不同的团队或项目可以使用不同的Vhost来管理资源和权限,提高整体的系统管理和安全性‌

  1. rabbitmq 支持的模式有哪几种,回答不好,好长时间都不用了,简历上写的有的招聘公司,要求rabbitmq

  2. ‌****简单模式****‌(Simple):一个生产者(P)和一个消费者(C),消息只能被单个消费者处理,适用于消息只能被单个消费者处理的场景‌12。

  3. ‌****工作队列模式****‌(Work Queue):一个生产者(P)和多个消费者(C1, C2),消息会被分派给不同的消费者,每个消费者接收不同的消息,适用于集群环境中做异步处理‌12。

  4. ‌****发布/订阅模式****‌(Publish/Subscribe):一个生产者(P)和多个消费者(C1, C2),消息会被复制多份,每个消费者接收相同的消息,适用于消息需要被多个消费者同时接收的场景‌12。

  5. ‌****路由模式****‌(Routing):生产者将消息发送到交换机,交换机根据路由键将消息路由到特定的队列,适用于有选择地接收消息的场景‌34。

  6. ‌****主题模式****‌(Topics):类似于路由模式,但可以使用模式匹配来选择性地接收消息,适用于需要根据特定规则接收消息的场景‌34。

  7. RabbitMQ 的核心组件有哪些?

  • Producer:消息生产者。

  • Consumer:消息消费者。

  • Exchange:路由消息到队列(类型:direct、topic、fanout、headers)。

  • Queue:存储消息的容器。

  • Broker:RabbitMQ 服务端,负责消息的接收、存储和转发。

  1. AMQP 协议的核心概念?
  • Connection(连接)、Channel(信道)、Virtual Host(虚拟主机)、Exchange(交换机)、Queue(队列)、Binding(绑定)。

二、Exchange 类型与路由

  1. Exchange 的四种类型及其区别?
  • Direct Exchange:严格匹配 Routing Key。

  • Topic Exchange:通过通配符(`*`、``)匹配 Routing Key。

  • Fanout Exchange:广播消息到所有绑定的队列。

  • Headers Exchange:根据消息头(Headers)的键值对匹配(较少使用)。

  1. 如何实现发布/订阅模式?
  • 使用 Fanout Exchange,将消息广播到所有绑定的队列。
  1. 如何实现路由模式?
  • 使用 Direct Exchange,通过 Binding Key 和 Routing Key 匹配。

三、消息可靠性

  1. 如何保证消息不丢失?
  • 持久化:设置消息的 `delivery_mode=2`,并声明持久化的 Exchange 和 Queue。‌

在RabbitMQ中,消息的持久性可以通过deliveryMode属性来设置。当deliveryMode设置为2时,表示消息需要被持久化存储。这意味着即使RabbitMQ服务器重启,这些消息也不会丢失。相反,如果deliveryMode设置为1(默认值),则消息不会被持久化,服务器重启后这些消息将会丢失‌。

  • 确认机制:

  • Publisher Confirms:生产者等待 Broker 的 ACK 确认。

  • Consumer Acknowledgements:消费者手动发送 ACK,失败时 NACK 或拒绝消息。

  1. 消息重复消费如何解决?
  • 消费者端实现幂等性(如数据库唯一索引、Redis 去重)。

四、高可用与集群

  1. RabbitMQ 集群如何实现高可用?
  • 镜像队列(Mirrored Queues):消息在多个节点间同步,主节点故障时从节点接管。

  • 集群搭建:通过 Erlang Cookie 同步,节点间共享元数据(队列元数据需显式同步)。

  1. 集群节点宕机如何处理?
  • 若队列为镜像队列,其他节点自动接管;若非镜像队列,队列不可用。
  1. 网络分区(Network Partition)如何处理?
  • 手动干预选择分区策略(如 pause_minority、autoheal),避免脑裂。

五、高级特性

  1. 什么是死信队列(DLX)?
  • 当消息被拒绝、过期或队列达到最大长度时,会被路由到死信队列。常用于订单超时处理。
  1. 如何实现延迟队列?
  • 方案1:利用 TTL + 死信队列(消息设置 TTL,队列设置死信交换机)。
java 复制代码
            String deadLetterExchange = "dlx.exchange";
            String deadLetterQueue = "dlx.queue";
            String deadRoutingKey = "dlx.routingkey";
            String orderExchange = "order.exchange";
            String orderQueue = "order.queue";
            String orderRoutingKey = "order.routingkey";
            args.put("x-dead-letter-exchange", deadLetterExchange);       // 绑定死信交换
            args.put("x-dead-letter-routing-key", deadRoutingKey);  // 设置死信路由键‌
            args.put("x-max-length", 5);                              // 队列最大容量
            args.put("x-message-ttl", 60000);                         // 队列中消息的全局
            channel.queueDeclare(deadLetterQueue,false,false,false,null);
            channel.exchangeDeclare(deadLetterExchange, BuiltinExchangeType.DIRECT);
            channel.queueBind(deadLetterQueue,deadLetterExchange,deadRoutingKey,null);
            channel.queueDeclare(orderQueue,true,false,false,args);
            channel.exchangeDeclare(orderExchange, BuiltinExchangeType.DIRECT, true);
            channel.queueBind(orderQueue, orderExchange, orderRoutingKey);
           AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
                   .expiration("60000") // 设置消息的TTL为60000毫秒(1分钟)
                    .build();*/
  • 方案2:使用 RabbitMQ 插件(如 `rabbitmq-delayed-message-exchange`)。
java 复制代码
Map<String, Object> args = new HashMap<>();
args.put("x-delayed-type", "direct");
channel = connection.createChannel();
channel.exchangeDeclare("delayed.exchange", "x-delayed-message", true, false, args);
channel.queueDeclare("delayed.queue",true,false,false,null);
channel.queueBind("delayed.queue","delayed.exchange","order.delay",null);
Map<String,Object> header = new HashMap<>();
header.put("x-delay", 5000); // 延迟5秒
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder()
        .headers(header)
        .deliveryMode(2)
        .expiration("10000")
        .build();
  1. 优先级队列如何实现?
  • 声明队列时设置 `x-max-priority` 参数,消息设置 `priority` 属性。

六、问题排查与优化

  1. 如何监控 RabbitMQ?
  • 使用管理插件(`rabbitmq-management`)查看队列状态、消息数量、节点状态等。

  • 监控工具:Prometheus + Grafana 监控内存、磁盘、消息积压等指标。

  1. 消息堆积如何处理?
  • 横向扩容消费者,增加并发消费能力。

  • 设置 QoS(预取计数),避免单个消费者过载。

  1. 内存和磁盘使用过高怎么办?
  • 调整内存阈值(`vm_memory_high_watermark`)。

  • 优化消息持久化策略,非必要消息不持久化。

七、应用场景与设计

  1. RabbitMQ 的典型应用场景?
  • 异步处理(如订单生成后发短信)、系统解耦、流量削峰(如秒杀)、事件驱动架构。
  1. 如何用 RabbitMQ 实现分布式事务?
  • 本地消息表:业务操作与消息记录在同一个本地事务,定时任务补偿未确认的消息。

  • 最大努力通知:多次重试确保消息最终被处理。

  1. 如何保证消息顺序性?
  • 单队列 + 单消费者,或使用分区有序(如 Kafka 分区键)。

八、对比与选型

  1. RabbitMQ vs Kafka?
  • RabbitMQ:适合复杂路由、低吞吐、高可靠场景(如金融交易)。

  • Kafka:适合高吞吐、日志流处理、大数据场景(如日志收集)。

  1. RabbitMQ 与其他 MQ(如 RocketMQ)对比?
  • RocketMQ 支持事务消息、顺序消息更强,适合超大规模分布式系统。

九、开放性问题

  1. 如何保证消息不重复且不丢失?
  • 生产者:Confirm 机制 + 重试。

  • 消费者:手动 ACK + 幂等性设计。

  • 存储层:消息持久化 + 死信队列兜底。

  1. 如何传输大文件?
  • 不建议直接通过消息传输,可上传至文件服务器,消息中传递下载链接。
相关推荐
茶杯梦轩1 天前
从零起步学习RabbitMQ || 第三章:RabbitMQ的生产者、Broker、消费者如何保证消息不丢失(可靠性)详解
分布式·后端·面试
回家路上绕了弯3 天前
深入解析Agent Subagent架构:原理、协同逻辑与实战落地指南
分布式·后端
用户8307196840823 天前
Spring Boot 集成 RabbitMQ :8 个最佳实践,杜绝消息丢失与队列阻塞
spring boot·后端·rabbitmq
用户8307196840825 天前
RabbitMQ vs RocketMQ 事务大对决:一个在“裸奔”,一个在“开挂”?
后端·rabbitmq·rocketmq
初次攀爬者6 天前
RabbitMQ的消息模式和高级特性
后端·消息队列·rabbitmq
初次攀爬者8 天前
ZooKeeper 实现分布式锁的两种方式
分布式·后端·zookeeper
让我上个超影吧9 天前
消息队列——RabbitMQ(高级)
java·rabbitmq
塔中妖9 天前
Windows 安装 RabbitMQ 详细教程(含 Erlang 环境配置)
windows·rabbitmq·erlang
断手当码农9 天前
Redis 实现分布式锁的三种方式
数据库·redis·分布式
初次攀爬者9 天前
Redis分布式锁实现的三种方式-基于setnx,lua脚本和Redisson
redis·分布式·后端