RabbitMQ 面试高频 20 问(PHP后端版)


1. 什么是 RabbitMQ?

RabbitMQ 是一个基于 AMQP 协议的开源消息中间件,用于系统之间的异步通信。

主要作用:

例如电商下单后,将发短信、发邮件、同步 ERP 等操作通过 RabbitMQ 异步执行,提高系统响应速度。


2. 为什么使用 RabbitMQ?

主要有三个原因:

异步

用户下单后立即返回结果。

不需要等待:

执行完成。

解耦

订单系统不需要关心:

是否存在。

削峰

高并发场景:

10000请求/秒
↓
RabbitMQ
↓
100请求/秒慢慢消费

防止数据库被压垮。


3. RabbitMQ 核心组件有哪些?

核心组件:

组件 作用
Producer 生产者
Consumer 消费者
Exchange 交换机
Queue 队列
Routing Key 路由键

消息流转:

Producer
    ↓
Exchange
    ↓
Queue
    ↓
Consumer

4. Exchange 有哪些类型?

四种:

Direct

精准匹配

order.create

Topic

通配符匹配

order.*
order.#

Fanout

广播

发送给所有绑定队列。

Headers

根据 Header 路由。

实际项目很少使用。


5. Direct 和 Topic 的区别?

Direct:

order.create

必须完全匹配。

Topic:

支持模糊匹配:

order.*
order.#

例如:

order.create
order.pay
order.cancel

都可以匹配。


6. RabbitMQ 如何保证消息不丢失?

需要三层保证。

生产者确认

Publisher Confirm

Producer
↓
RabbitMQ
↓
ACK

队列持久化

durable = true

消息持久化

delivery_mode = 2

消费者ACK

basic_ack()

消息处理完成后确认。


7. 什么是 Publisher Confirm?

生产者发送消息后:

RabbitMQ返回ACK。

Producer
 ↓
MQ
 ↓
ACK

收到ACK:

表示RabbitMQ已接收。

未收到ACK:

重试发送。

用于保证生产者消息不丢失。


8. 什么是 Consumer ACK?

消费者处理成功后:

basic_ack()

通知RabbitMQ删除消息。

如果消费者异常退出:

ACK未发送
↓
消息重新投递

避免消息丢失。


9. 什么是消息持久化?

RabbitMQ重启后消息仍然存在。

需要:

队列持久化

durable=true

消息持久化

delivery_mode=2

两者缺一不可。


10. RabbitMQ 如何实现延迟队列?

常见方案:

TTL + Dead Letter Queue

流程:

订单创建
 ↓
延迟队列
(TTL=30分钟)
 ↓
死信队列
 ↓
取消订单

典型场景:

30分钟未支付自动取消订单。


11. 什么是死信队列?

无法正常消费的消息进入死信队列。

出现条件:

消息过期

TTL到期。

队列满

超过最大长度。

消费被拒绝

basic_nack()

12. 什么是 TTL?

Time To Live(消息存活时间)

例如:

x-message-ttl = 60000

表示:

60秒后过期

过期消息可转入死信队列。


13. RabbitMQ 如何实现订单超时取消?

标准流程:

创建订单
 ↓
发送延迟消息
(TTL=30分钟)
 ↓
进入死信队列
 ↓
检查订单状态
 ↓
未支付则取消

这是电商面试经典题。


14. RabbitMQ 会重复消费吗?

会。

例如:

消费成功
↓
ACK发送失败
↓
MQ认为失败
↓
重新投递

导致重复消费。


15. 如何解决重复消费?

保证幂等性。

常见方案:

Redis

SETNX(message_id)

唯一索引

UNIQUE(message_id)

业务状态判断

已处理
↓
直接返回

16. 什么是幂等性?

同一个请求执行多次。

结果保持一致。

例如:

支付成功
支付成功
支付成功

订单状态仍然:

已支付

不会重复扣款。


17. RabbitMQ 消息积压怎么办?

增加消费者

1个
↓
10个

提高prefetch

basic_qos()

优化消费逻辑

例如:

批量插入数据库

临时扩容

增加消费机器。


18. 什么是 Prefetch?

限制消费者一次拉取消息数量。

例如:

prefetch_count = 10

表示:

处理完10条
再拉下一批

防止单个消费者被压垮。


19. RabbitMQ 和 Redis 消息队列区别?

对比项 RabbitMQ Redis
可靠性 一般
ACK机制 支持 较弱
死信队列 支持 不支持
延迟队列 支持 需自己实现
吞吐量 较高 非常高
场景 业务消息 简单异步

面试结论:

业务场景优先RabbitMQ
极高性能场景可考虑Redis

20. RabbitMQ 在项目中的实际应用?

在电商项目中,我使用 RabbitMQ 实现订单异步处理。

用户下单后:

订单创建
 ↓
RabbitMQ
 ↓
短信通知
邮件通知
ERP同步
库存同步
积分发放

这样做有三个好处:

同时为了保证消息可靠性,我使用:

避免消息丢失和重复消费。