主题切换
延迟队列
一、什么是死信交换机
当队列中的消息满足以下任一条件时,会成为死信(Dead Letter):
- 消费者使用
basic.reject或basic.nack声明消费失败,且requeue=false(不重回原队列) - 消息是过期消息,超时未被消费
- 消息投递的队列已满,无法接收新消息
如果队列配置了 dead-letter-exchange 属性,指定了交换机,队列中的死信就会投递到这个交换机中,该交换机即为死信交换机(DLX)。
二、TTL(消息存活时间)规则
TTL(Time-To-Live)指消息的存活时间,超时未消费的消息会变为死信,有两种设置方式:
- 队列级别:为队列设置统一的消息存活时间
- 消息级别:为单条消息单独设置存活时间
当两者同时设置时,哪个存活时间短就以哪个为准,消息按较短的TTL过期。
三、延迟队列的两种实现方式
延迟队列的核心是让消息延迟一段时间后再被消费,RabbitMQ 提供两种实现方式:
1. 死信交换机 + TTL(原生方式)
- 配置流程:
- 定义普通队列,并设置TTL和死信交换机
- 消息发送到普通队列,TTL超时后变为死信
- 死信被投递到死信交换机,再转发到目标延迟队列,由消费者监听
- 适用场景:简单的延迟需求,无需额外安装插件
2. DelayExchange 插件方式
- 实现流程:
- 安装
rabbitmq_delayed_message_exchange插件 - 声明交换机,设置
delayed="true" - 发送消息时,通过
x-delay头设置延迟时间
- 安装
- 优势:无需依赖死信机制,直接支持延迟消息,更灵活方便
四、典型业务场景
- 超时订单:订单创建后30分钟未支付,自动取消并释放库存
- 限时优惠:活动开始前定时发送提醒消息
- 定时发布:延迟发布通知、公告等内容
五、面试相关问题
问:什么是死信交换机?死信的产生条件有哪些?答: 死信交换机(DLX)是接收死信的交换机。当队列配置了死信交换机后,满足以下条件的消息会成为死信并被转发:
- 消费者拒绝消费(reject/nack)且不重回队列;
- 消息TTL超时未消费;
- 队列已满,消息无法投递。
问:TTL的设置方式和优先级规则是什么?答: TTL支持队列级别和消息级别两种设置方式。当两者同时配置时,哪个存活时间短就以哪个为准,消息会按较短的TTL过期。
问:延迟队列有哪些实现方式?各自的优缺点是什么?答: 有两种实现方式:
- 死信交换机+TTL:原生方式,无需插件,但依赖死信机制,实现较繁琐;
- DelayExchange插件:直接支持延迟消息,配置更简单,但需要额外安装插件。
问:项目中什么场景会用到延迟队列?答: 常用于超时订单处理、限时优惠提醒、定时任务调度等场景,比如志愿者报名超时未确认时自动取消名额,就可以用延迟队列实现。