死信交换机概念
死信交换机(Dead Letter Exchange,DLX)是 RabbitMQ 中用于接收无法被正常消费的消息的特殊交换机。
什么是死信
当消息满足以下三种条件之一时,会成为死信(Dead Letter):
- 消息被拒绝:消费者调用
basicNack或basicReject,且requeue=false - 消息过期:消息 TTL 到期未被消费
- 队列满:队列达到最大长度,新消息无法入队
死信不会被丢弃,而是被路由到指定的死信交换机,由死信交换机转发到死信队列。
DLX 转发机制
死信交换机的工作流程:
Java
生产者 -> 业务交换机 -> 业务队列 -> (死信条件触发) -> DLX -> 死信队列 -> 死信消费者
关键规则:
- 死信交换机本质是一个普通交换机,可以是 direct、fanout、topic 等任意类型
- 消息被转发到 DLX 时,routingKey 保持原样,不会被修改
- 死信消息的 headers 中会新增
x-death字段,记录死信次数、时间、原因等信息 x-death是一个列表,每次死信都会在列表头部追加一条记录
Java 示例:声明 DLX
text
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.BuiltinExchangeType;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class DlxExchangeExample {
private static final String DLX_EXCHANGE = "dlx.exchange";
private static final String DLX_QUEUE = "dlx.queue";
private static final String BUSINESS_EXCHANGE = "business.exchange";
private static final String BUSINESS_QUEUE = "business.queue";
public static void main(String[] args) throws IOException, TimeoutException {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost("localhost");
factory.setPort(5672);
factory.setUsername("guest");
factory.setPassword("guest");
try (Connection connection = factory.newConnection();
Channel channel = connection.createChannel()) {
// 1. 声明死信交换机(普通 direct 交换机)
channel.exchangeDeclare(DLX_EXCHANGE, BuiltinExchangeType.DIRECT, true);
// 2. 声明死信队列并绑定到死信交换机
channel.queueDeclare(DLX_QUEUE, true, false, false, null);
channel.queueBind(DLX_QUEUE, DLX_EXCHANGE, "dlx.routingkey");
// 3. 声明业务交换机
channel.exchangeDeclare(BUSINESS_EXCHANGE, BuiltinExchangeType.DIRECT, true);
// 4. 声明业务队列,指定死信交换机
channel.basicConsume(BUSINESS_QUEUE, false, (consumerTag, delivery) -> {
// 业务处理失败,拒绝消息
channel.basicNack(delivery.getEnvelope().getDeliveryTag(), false, false);
}, consumerTag -> {});
System.out.println("DLX 声明完成");
}
}
}
x-death 字段结构
x-death 包含以下信息:
| 字段 | 类型 | 说明 |
|---|---|---|
| count | Long | 该队列的死信次数 |
| exchange | String | 上一次投递的交换机 |
| queue | String | 上一次投递的队列 |
| routing-keys | List | 路由键列表 |
| time | Date | 死信发生时间 |
| reason | String | 死信原因(expired/rejected/overflow) |
x-death可用于追踪死信链路,但会增加消息体积,生产环境建议按需消费后清理。
要点总结
- 死信产生的三种条件:被拒绝(requeue=false)、TTL 过期、队列溢出
- DLX 是普通交换机,支持 direct/fanout/topic 类型
- 消息转发到 DLX 时 routingKey 不变
x-death记录死信链路信息,可用于问题排查- 死信交换机必须在队列声明时通过
x-dead-letter-exchange参数指定
📝 发现内容有误?点击此处直接编辑