参考RabbitMQ的死信队列详解 - 简书 (jianshu.com)
以下是基于spring cloud 2.1.4+rabbitmq-server-3.8.22的实现代码
死信队列:当消息成为死信(Dead message)后,可以被重新发送到另一个交换机,这个交换机
就是死信交换机(DLX:dead letter exchange),死信交换机在转发给死信队列
消息成为死信的三种条件:
- 队列消息长度达到了限制,下一个消息来的时候不能存储到队列中,这个消息就变成了dead状态
- 消费者拒绝接收消息(basicNack/basicReject),并且不把消息重新放入原目标队列中,requeue=false
- 原队列存在消息过期的设置,消息达到超时时间未被消费。
Springboot 利用死信队列加TTL可以实现延迟队列的功能
消息进入死信队列(Dead-Letter Queue,DLQ)通常是自动的,前提是RabbitMQ服务器和队列已经正确配置了相关的死信交换机(Dead-Letter Exchange)和死信路由键。
以下是一些导致消息自动进入死信队列的情况:
1. **消息被拒绝(basicReject或basicNack)**:如果消费者调用了`basicReject`或`basicNack`方法拒绝消息,并且指定了`requeue=false`,则消息将不会被重新放回队列,而是根据配置发送到死信交换机。
2. **队列长度限制**:如果队列达到了其长度限制(`x-max-length`),新发送的消息或被拒绝的消息将被发送到死信交换机。
3. **消息过期**:如果消息或队列被设置了过期时间(`x-message-ttl` 和 `x-expires`),并且消息在队列中存活的时间超过了这个时间,它将被发送到死信交换机。
4. **队列绑定**:死信交换机可以与一个或多个队列绑定,消息到达死信交换机后,将根据绑定的路由键路由到相应的死信队列。
为了使用死信队列,通常需要进行以下配置:
- **死信交换机**:需要定义一个死信交换机,并将其与死信队列绑定。
- **队列绑定**:普通队列需要绑定到死信交换机,并指定一个死信路由键。
- **消息或队列属性**:设置消息的过期时间或队列的长度限制。
例如,创建死信交换机和绑定可以这样配置:
```java
@Bean
public DirectExchange deadLetterExchange() {
return new DirectExchange("deadLetterExchange");
}
@Bean
public Queue deadLetterQueue() {
Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", ""); // 默认交换机,可以指定其他交换机
// 可以设置死信路由键
args.put("x-dead-letter-routing-key", "deadLetterRoutingKey");
return new Queue("deadLetterQueue", true, false, args);
}
@Bean
public Binding deadLetterBinding() {
return BindingBuilder.bind(deadLetterQueue()).to(deadLetterExchange()).with("deadLetterRoutingKey");
}
```
请注意,死信队列的配置和使用应根据你的具体业务需求和消息处理逻辑来确定。正确配置死信队列可以帮助处理无法正常消费的消息,避免消息丢失,并提供一种错误处理和调试的手段。