【面试】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. 性能优化:大流量场景如何处理堆积和限流。

相关推荐
我是华为OD~HR~栗栗呀43 分钟前
前端面经-高级开发(华为od)
java·前端·后端·python·华为od·华为·面试
MongoVIP2 小时前
AI提示词应用
人工智能·职场和发展·简历优化·简历制作
白露与泡影2 小时前
2025互联网大厂高频Java面试真题解析
java·开发语言·面试
hn小菜鸡2 小时前
LeetCode 3132.找出与数组相加的整数 II
算法·leetcode·职场和发展
微笑尅乐2 小时前
数组模拟加法——力扣66.加一
算法·leetcode·职场和发展
aloha_7893 小时前
新国都面试真题
jvm·spring boot·spring·面试·职场和发展
我是华为OD~HR~栗栗呀4 小时前
测试转C++开发面经(华为OD)
java·c++·后端·python·华为od·华为·面试
Dream it possible!4 小时前
LeetCode 面试经典 150_哈希表_快乐数(45_202_C++_简单)(哈希表;快慢指针)
leetcode·面试·散列表
用户094 小时前
MVI架构如何改变Android开发模式
android·面试·kotlin