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. 如何传输大文件?
  • 不建议直接通过消息传输,可上传至文件服务器,消息中传递下载链接。
相关推荐
悻运2 小时前
Spark论述及其作用
大数据·分布式·spark
码熔burning3 小时前
【MQ篇】RabbitMQ之工作队列模式!
java·分布式·rabbitmq·mq
掘金-我是哪吒4 小时前
分布式微服务系统架构第118集:Future池管理容器-CompletableFuture
分布式·微服务·云原生·架构·系统架构
CXH7285 小时前
hadoop分布式部署
大数据·hadoop·分布式
£菜鸟也有梦7 小时前
探索Hadoop:大数据世界的基石
大数据·hadoop·分布式
Java林间8 小时前
Zookeeper是什么?基于zookeeper实现分布式锁
分布式·zookeeper·wpf
云闲不收8 小时前
CAP原理,zookeeper是强一致性么?为什么zookeeper不满足线性一致性依然可以实现分布式锁?
分布式·zookeeper·云原生
皮卡兔子屋11 小时前
分布式理论和事务
分布式
青灯文案112 小时前
RabbitMQ 详解(核心概念)
分布式·rabbitmq