rabbitmq死信队列需显式配置dlx和dlq:先声明dlx(如direct交换机),再声明dlq并绑定到dlx,最后在业务队列中通过x-dead-letter-exchange和x-dead-letter-routing-key指定路由,三者名称与键必须严格一致,否则死信将丢失。

在 RabbitMQ 中配置死信交换机(DLX)和死信队列,核心是为普通队列设置 x-dead-letter-exchange 和可选的 x-dead-letter-routing-key 参数,并声明一个专门接收死信的队列。超时(TTL)和队列长度限制触发的死信,都会被自动路由到 DLX 对应的死信队列。
声明死信交换机与死信队列
死信队列本质就是一个普通队列,但需绑定到专用的死信交换机(可以复用已有 exchange,但推荐独立命名便于维护)。不需要特殊参数,只需确保它能被 DLX 正确路由:
- 创建一个名为
dlx.exchange的 exchange(类型通常为direct或topic) - 声明一个队列如
queue.dlx,并绑定到该 exchange,routing key 可设为dlq.routing.key - 这个队列就是最终消费死信的地方,后续由消费者监听它
为业务队列配置 DLX 和 TTL/长度限制
在声明业务队列时,通过 arguments 设置死信相关参数和触发条件:
-
x-dead-letter-exchange:指定死信转发的目标 exchange(如dlx.exchange) -
x-dead-letter-routing-key:可选,指定死信发往 DLX 时的 routing key(默认为原消息的 routing key) -
x-message-ttl:队列级 TTL(毫秒),所有入队消息统一过期时间;或用expiration属性为单条消息设 TTL -
x-max-length或x-max-length-bytes:限制队列最大消息数或总字节数,超出后旧消息被丢弃并可能转为死信(需配合x-overflow=reject-publish-dlq或drop-head)
注意:x-max-length 默认溢出策略是 drop-head(丢头),不会产生死信;要让被挤出的消息变成死信,必须显式设置 x-overflow=reject-publish-dlq(RabbitMQ 3.9+)或使用 drop-head + 手动确认失败模拟死信(不推荐)。
Java 客户端配置示例(Spring AMQP)
使用 Spring Boot + spring-boot-starter-amqp 时,可通过 @Bean 声明组件:
@Bean
public Exchange dlxExchange() {
return new DirectExchange("dlx.exchange");
}
@Bean
public Queue dlqQueue() {
return QueueBuilder.durable("queue.dlx").build();
}
@Bean
public Binding dlqBinding() {
return BindingBuilder.bind(dlqQueue()).to(dlxExchange());
}
@Bean
public Queue businessQueue() {
Map<string object> args = new HashMap();
args.put("x-dead-letter-exchange", "dlx.exchange");
args.put("x-dead-letter-routing-key", "dlq.routing.key");
args.put("x-message-ttl", 60000); // 60秒过期
args.put("x-max-length", 10); // 最多存10条
args.put("x-overflow", "reject-publish-dlq"); // 溢出时转死信
return QueueBuilder.durable("queue.business").withArguments(args).build();
}</string>
这样,超时未被消费或因长度限制被挤出的消息,就会自动发送到 queue.dlx 中。
验证与注意事项
死信机制依赖 RabbitMQ 内部检查,不是实时触发:
- TTL 过期检测有延迟(通常秒级),并非精确到毫秒
- 队列满时,只有新消息发布失败且配置了
reject-publish-dlq才会生成死信;drop-head不产生死信 - 消息被 consumer 拒绝(
basic.reject/basic.nack)且设置了requeue=false,也会进入 DLX(前提是队列配置了 DLX) - 确保死信队列已声明、绑定,否则死信会丢失(RabbitMQ 默认丢弃无法路由的死信)
不复杂但容易忽略细节。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











