RabbitMQ 面试里经常把两个问题放在一起问死信交换机是什么延迟队列怎么做这两个问题不是孤立的因为 RabbitMQ 原生延迟队列的经典实现就是TTL 死信交换机。一句话概括死信交换机负责接收“消费失败、消息过期、队列满了”的死信延迟队列可以利用 TTL 让消息先在等待队列里过期再通过 DLX 转发到真正的业务队列。超时未消费生产者ttl.directttl.queue设置 TTLdl.direct死信交换机dl.queue业务消费消费者处理订单关闭/定时发布死信是什么一个队列里的消息满足下面任意一种情况就可能变成死信变成死信的原因说明消费者拒绝basic.reject或basic.nack并且requeuefalse消息过期消息 TTL 到期仍然没有被消费队列满了队列达到长度限制较早消息可能被挤出如果队列配置了dead-letter-exchange这些死信不会直接消失而是会被投递到指定交换机。这个交换机就叫死信交换机也就是 DLX。reject/nack 且 requeuefalseTTL 到期队列满了是否Queue 中的消息发生什么变成死信是否配置 dead-letter-exchange投递到死信交换机 DLX消息被丢弃或按策略处理死信交换机本质上仍然是普通交换机只是它接收的是其他队列转过来的死信消息。TTL 是什么TTL 是Time-To-Live表示消息可以存活多久。RabbitMQ 里 TTL 常见有两种设置方式TTL 类型设置位置特点队列 TTL队列参数x-message-ttl队列里的所有消息统一过期时间消息 TTL发送消息时设置 expiration每条消息可以有不同过期时间如果消息在 TTL 时间结束后仍然没有被消费就会变成死信。只要这个队列绑定了 DLX消息就会被转发到死信交换机。用 TTL DLX 实现延迟队列延迟队列的意思是消息不是立刻被消费而是等待一段时间后再被消费。典型场景场景延迟动作超时订单下单 30 分钟未支付自动关闭限时优惠活动结束后自动下架定时发布到点后发布文章、视频或公告TTL DLX 的实现思路如下消费者业务队列死信交换机TTL 队列生产者消费者业务队列死信交换机TTL 队列生产者不绑定消费者等待 TTL 过期发送延迟消息消息过期变成死信根据 dead-letter-routing-key 路由消费真正的业务消息这套设计的关键点是TTL 队列只是“等待室”真正处理业务的是死信交换机后面的业务队列。TTL 延迟队列的坑TTL DLX 很好理解但它不是完美的定时任务系统。最容易被追问的是队头阻塞。如果每条消息自己设置不同 TTLRabbitMQ 并不会为了后面的短 TTL 消息主动越过前面的长 TTL 消息。过期消息通常要到达队头时才会被丢弃或死信转发所以可能出现这种情况未到期挡在队头消息 ATTL 30 分钟消息 BTTL 5 秒消息 CTTL 10 秒后面的短 TTL 消息不能按预期立刻死信这会导致“理论上 5 秒后执行”的消息实际被前面的长 TTL 消息挡住延迟变得不稳定。常见规避方式有三种方案说明固定延迟档位5 分钟、30 分钟、2 小时分别建不同 TTL 队列使用 DelayExchange 插件每条消息通过x-delay表达延迟时间语义更直观使用专业调度组件延迟精度和任务管理要求高时用 XXL-JOB、调度表等方案所以 TTL DLX 更适合延迟档位比较少、精度要求不极端的业务比如订单 30 分钟超时关闭。DelayExchange 插件课件里也提到 RabbitMQ 的延迟队列插件DelayExchange。它的本质还是交换机只是在交换机上增加了延迟能力。使用方式通常是安装 RabbitMQ 延迟插件。声明交换机时设置delayedtrue。发送消息时在 header 中设置x-delay值为延迟毫秒数。延迟时间到后交换机再把消息路由到队列。x-delay30000等待 30 秒后路由生产者DelayExchange业务队列消费者插件方案比 TTL DLX 更直观因为消息不需要先进入一个专门的 TTL 等待队列。但它依赖插件安装线上环境要确认运维和版本支持。两种延迟方案怎么选方案优点缺点适合场景TTL DLX不依赖插件机制通用队列设计稍绕消息级 TTL 可能有队头阻塞延迟时间档位少、环境保守DelayExchange使用直观每条消息可设置x-delay依赖插件延迟时间灵活、运维允许安装插件如果面试官问“延迟队列是不是死信队列”可以这样答延迟队列不是死信队列但可以用死信机制实现。TTL 队列里的消息过期后变成死信再由死信交换机转发到业务队列从效果上实现延迟消费。面试回答模板可以这样答RabbitMQ 中死信是指消息因为消费失败并且不重新入队、TTL 过期、队列满了等原因无法正常消费。如果队列配置了 dead-letter-exchange这些消息会被投递到死信交换机。延迟队列可以用 TTL 死信交换机实现先把消息发到设置了 TTL 的等待队列队列不绑定消费者消息过期后变成死信再通过 DLX 路由到真正的业务队列。项目里常见场景有超时订单、限时优惠和定时发布。不过 TTL 方案要注意消息级 TTL 的队头阻塞问题如果延迟时间非常灵活或精度要求更高可以安装 DelayExchange 插件发送消息时通过x-delay设置延迟时间。小结死信交换机解决的是“异常消息去哪儿”延迟队列解决的是“消息什么时候消费”。两者结合时TTL 负责等待DLX 负责转发。延迟需求TTL 等待过期变死信DLX 转发业务队列消费