一、基础概念
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 分钟未支付自动取消。
-
解决方法:
-
TTL + DLX:设置消息 TTL,过期后进入死信队列,由消费者取消订单。
-
延迟队列插件: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 时,通常考察三点:
-
消息可靠性:如何避免丢失和重复。
-
高可用:集群模式、故障切换方案。
-
性能优化:大流量场景如何处理堆积和限流。