【面试】RabbitMQ 常见问题

一、基础概念

1. RabbitMQ 是什么?

  • 定义:基于 AMQP 协议的消息中间件,用于系统解耦、异步处理、削峰填谷。

  • 场景:电商下单 → 订单服务写入消息 → 消费者服务分别处理短信、库存、物流。

  • 解决方法

    • 用 MQ 解耦,提高系统可靠性。

    • 下游系统挂掉时,消息仍存储在队列中,不会丢失。

2. RabbitMQ 和 Kafka 的区别?

  • RabbitMQ:强调可靠性,消息确认机制多,适合金融、电商等强一致性场景。

  • Kafka:强调高吞吐,适合日志收集、大数据分析。

  • 解决方法

    • 金融、交易系统 → RabbitMQ

    • 日志、埋点、大数据流处理 → Kafka

二、消息可靠性

3. 如何保证消息不丢失?

  • 场景:用户支付消息丢失 → 金额到账但系统未更新。

  • 解决方法

    • 生产端:开启 Confirm 模式(确认消息已到 Broker)。

    • Broker 端:队列设置 durable=true,消息 persistent=true,避免宕机丢失。

    • 消费端:使用 手动 ACK,消费完成后再确认。

    • 失败处理:消息进入 死信队列(DLX),由补偿服务处理。

4. 如何避免消息重复消费?

  • 场景:网络抖动,消费者 ack 超时,消息被重新投递,导致库存多次扣减。

  • 解决方法

    • 消息唯一 ID(messageId)。

    • 消费前检查 Redis/DB 是否已处理过。

    • 数据库唯一键约束,保证幂等性。

📌 实战:扣库存时加唯一约束 (orderId, productId),即使消费两次也只扣一次。

5. 什么是死信队列(DLX)?什么时候会产生?

  • 场景:消息过期、队列满、被拒绝(nack)时。

  • 解决方法

    • 定义死信队列,绑定到原队列。

    • 将异常消息路由到 DLX,由专门的补偿服务消费。

    • 配合监控报警,人工干预。

三、高可用与集群

6. RabbitMQ 集群模式?

  • 场景:单机宕机,导致业务无法继续。

  • 解决方法

    • 普通集群:适合开发测试。

    • 镜像队列:数据复制多份,防止单点故障。

    • Quorum Queue(推荐):基于 Raft 协议,天然支持高可用。

📌 实战:生产环境部署 Quorum Queue(3 节点),即使 1 台宕机仍能正常服务。

7. 镜像队列 vs Quorum Queue?

  • 镜像队列:主从同步,性能瓶颈大。

  • Quorum Queue:基于日志复制,性能更高,数据一致性更强。

  • 解决方法 :新项目优先选择 Quorum Queue,老系统逐步迁移。

四、性能优化

8. 如何提升 RabbitMQ 吞吐量?

  • 场景:秒杀系统,峰值请求 5w/s,MQ 堆积严重。

  • 解决方法

    • 生产端:批量 Confirm,减少网络交互。

    • 消费端:设置 prefetch > 1,批量 ack。

    • 队列拆分:按业务/用户维度拆分,避免单队列瓶颈。

    • 硬件优化:SSD 存储、内存充足。

9. 什么是 prefetch?

  • 定义:限制消费者一次最多获取的未确认消息数。

  • 场景:一个慢消费者阻塞了大量消息,导致其他消费者空闲。

  • 解决方法

    • 设置合理的 prefetch(如 10 或 100)。

    • 实现 公平调度,避免部分消费者过载。

五、应用场景

10. 如何实现延迟消息?

  • 场景:订单 30 分钟未支付自动取消。

  • 解决方法

    1. TTL + DLX:设置消息 TTL,过期后进入死信队列,由消费者取消订单。

    2. 延迟队列插件:rabbitmq_delayed_message_exchange,更灵活。

11. 如何保证消息顺序?

  • 场景:同一用户的操作必须按顺序(下单 → 支付 → 发货)。

  • 解决方法

    • 单队列 + 单消费者(简单但吞吐低)。

    • 按业务 key 路由,例如 userId 作为 routingKey,确保同一用户的消息进同一队列。

12. 如何处理消息堆积?

  • 场景:突发高并发,消费速度跟不上,消息堆积。

  • 解决方法

    • 增加消费者并发数。

    • 批量 ack,提升消费效率。

    • 使用死信队列丢弃过期消息。

    • 临时扩容 RabbitMQ 节点。

六、实战与扩展

13. 如何实现优先级队列?

  • 场景:VIP 用户订单需要优先处理。

  • 解决方法

    • 声明队列时设置 x-max-priority。

    • 生产者发送消息时设置 priority 属性。

    • 消费端优先消费高优先级消息。

14. 如何监控 RabbitMQ?

  • 场景:业务运维需要监控队列堆积、消费速率。

  • 解决方法

    • 官方 Management 插件(Web UI)。

    • Prometheus + Grafana,监控消息量、ack 数、死信数。

    • 设置告警规则(如队列堆积 > 1w 触发报警)。

15. 如何防止消息风暴(消息量过大导致系统崩溃)?

  • 场景:秒杀开始瞬间,短时间产生百万级消息。

  • 解决方法

    • 设置 prefetch 限流,防止单消费者过载。

    • 消费端降级处理(非核心消息直接丢弃)。

    • 利用消息 TTL + 死信队列,过期自动清理无效消息。


✅ 总结:

面试 RabbitMQ 时,通常考察三点:

  1. 消息可靠性:如何避免丢失和重复。

  2. 高可用:集群模式、故障切换方案。

  3. 性能优化:大流量场景如何处理堆积和限流。

相关推荐
kobe_OKOK_3 小时前
rabbitmq 入门知识点
分布式·rabbitmq·ruby
王嘉俊9253 小时前
深入浅出 全面剖析消息队列(Kafka,RabbitMQ,RocketMQ 等)
分布式·kafka·消息队列·rabbitmq·rocketmq
要做朋鱼燕3 小时前
【C++】 priority_queue 容器模拟实现解析
开发语言·c++·笔记·职场和发展
做就对了66664 小时前
驱动员工的核心:少谈“大道理”,多解“人心”
职场和发展·职场·管理·团队管理·销售
围巾哥萧尘5 小时前
Anthropic Claude for Chrome🧣
面试
Zhao_yani5 小时前
RabbitMQ相关知识
分布式·rabbitmq
要记得喝水6 小时前
C#某公司面试题(含题目和解析)--1
开发语言·windows·面试·c#·.net
墨染点香6 小时前
LeetCode 刷题【61. 旋转链表】
算法·leetcode·职场和发展
岁忧7 小时前
(LeetCode 面试经典 150 题) 200. 岛屿数量(深度优先搜索dfs || 广度优先搜索bfs)
java·c++·leetcode·面试·go·深度优先