
一、什么是死信 Dead Letter一条消息无法被正常消费会变成死信触发转发逻辑只有满足下面三种情况之一才会成为死信消费者调用basicNack / basicReject并且参数requeuefalse不重回原队列消息在队列设置了 TTL 过期没人消费自动失效队列达到最大长度限制新消息挤掉头部旧消息。死信不会直接丢弃而是交给预先绑定的DLX 死信交换机由交换机路由到专门的死信队列DLQ。二、死信队列核心组成DLX DLQDLXDead Letter Exchange死信交换机普通交换机类型不限direct/fanout/topic专门接收所有死信消息DLQ 死信队列绑定在 DLX 下用来存放死信消息人工排查、补偿处理。关键配置给业务队列绑定死信能力创建普通业务队列时附加两个参数x-dead-letter-exchange指定死信交换机名称x-dead-letter-routing-key转发死信时使用的路由 key不填默认复用原消息 routingKey。三、完整流转流程生产者发送消息 → 业务交换机 → 业务队列消费者消费消息出现异常拒绝消息nack(requeuefalse)RabbitMQ 识别该消息为死信自动转发到配置好的 DLX 死信交换机DLX 根据路由 key把消息投递到死信队列 DLQ业务侧单独监听 DLQ处理失败消息打印异常告警、人工修复后重新投递。四、死信队列两大核心业务场景场景 1存储消费失败消息兜底不丢数据最基础用途。消息消费报错参数非法、数据库异常、第三方接口故障不直接丢弃存入死信队列避免数据丢失支持事后排查重跑。场景 2结合 TTL 实现延迟重试队列TTLDLX 延迟方案这是企业最常用的重试方案也是容易和纯死信混淆的点新建延迟重试队列设置 TTL如 10s同时配置它的 DLX 指向原业务交换机消费失败后手动 ack 原消息再用生产者 API 把消息发进延迟队列消息在延迟队列等待 10s 过期自动变成死信通过 DLX 路由回业务队列再次消费循环重试通过 header 记录重试次数达到上限后再转发到最终死信队列。这里区分重试队列只是临时中转队列它的死信目标是业务队列真正的 DLQ 最终死信队列存放重试多次仍失败的消息不再重试。五、requeuetrue 和 死信的关键区别高频坑点nack(requeuetrue)消息直接扔回原队列头部不会产生死信立刻重新消费极易造成重试风暴故障时打垮服务nack(requeuefalse)消息判定为死信转发 DLX 进入死信队列不会立刻重试。六、生产使用规范与避坑死信队列必须单独监听不能和业务队列共用消费者收到死信后触发告警钉钉 / 邮件及时介入不要无限重试消息在消息 Header 记录x-retry-count超过 3~5 次转发至最终死信队列防止无限循环区分两种队列职责重试队列用于延迟重试过期自动回业务队列死信队列 DLQ兜底存储彻底失败数据人工处理死信消息保留原始 header、body、异常标识方便定位报错原因死信队列也要设置过期时间防止堆积海量无效消息占满磁盘。七、对比延迟交换机插件方案TTLDLX 依赖死信机制实现延迟无需插件所有 RabbitMQ 版本通用但存在队头阻塞x-delayed-message延迟交换机插件不依赖死信交换机内部缓存延迟消息每条消息独立延迟无阻塞但需要安装插件。简短总结消息 nack 不重回队列、TTL 过期、队列满溢三种情况会产生死信给业务队列配置 DLX 死信交换机死信自动路由到死信队列 DLQ死信队列一是兜底保存消费失败消息防止丢失二是搭配 TTL 做成延迟重试队列开发禁止 requeuetrue 即时重推通过死信机制可控重试达到最大重试次数后转入最终死信人工处理。