DLX:死信队列 DEAD-LETTER_EXCHANGE,也可以称之为死信交换机,当消息在一个队列中变为过期的死信(DEAD_MESSAGE)之后,它可以被重新发送到另一个交换机中,这个交换即就是死信交换机,绑定死信交换机的队列就是死信队列而消息变成死信的原因可以有以下几种
- 消息被拒绝消费
- 消息过期
- 消息队列达到最大长度
想要使用死信队列,只需要在定义队列的时候定义参数即可
x-dead-letter-exchange 并指定交换机即可
消息过长转移到死信队列
配置类
定义一个死信交换机和死信队列
@Configuration
public class DeadRabbitConfig {
// 声明注册direct模式的交换机
@Bean
public DirectExchange deadExchange() {
return new DirectExchange("dead_direct_exchange", true, false);
}
// 设置死信队列
@Bean
public Queue deadQueue() {
return new Queue("dead_direct_queue", true);
}
@Bean
public Binding deadBinding() {
return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("dead_direct_message");
}
}
将正常的交换机和死信交换机进行绑定
@Configuration
public class TTLRabbitConfig {
// 声明注册direct模式的交换机
@Bean
public DirectExchange ttlDirectExchange() {
return new DirectExchange("ttl_direct_exchange", true, false);
}
@Bean
public DirectExchange ttlMessageDirectExchange() {
return new DirectExchange("ttl_message_direct_exchange", true, false);
}
// 设置队列过期时间
@Bean
public Queue ttlQueue() {
//设置队列参数
Map<String, Object> args = new HashMap<>();
//x-message-ttl: 表示过期时间
args.put("x-message-ttl", 5000);
//绑定死信交换机
args.put("x-dead-letter-exchange","dead_direct_exchange");
//绑定死信key direct模式下需要配置
args.put("x-dead-letter-routing-key","dead");
return new Queue("ttl_direct_queue", true, false, false, args);
}
// 设置消息过期时间
@Bean
public Queue ttlMessageQueue() {
return new Queue("ttl_message_direct_queue", true);
}
// 完成交换机和队列,路由key的绑定
@Bean
public Binding ttlBinding() {
return BindingBuilder.bind(ttlQueue()).to(ttlDirectExchange()).with("ttl");
}
@Bean
public Binding ttlMessageBinding() {
return BindingBuilder.bind(ttlMessageQueue()).to(ttlMessageDirectExchange()).with("ttL_message");
}
}
如果是direct模式下,绑定死信交换机的同时还需要绑定死信队列的路由key,fanout模式不需要
测试类
public boolean ttlDirectOrder(String userId, String productId, Integer num) {
//保存订单业务执行
String orderId = UUID.randomUUID().toString();
log.info("订单业务执行完毕");
log.info("开始异步执行消息分发");
//通过MQ进行消息分发
//定义交换机
String exchangeName = "ttl_direct_exchange";
//消息分发
rabbitTemplate.convertAndSend(exchangeName, "ttl", orderId);
return false;
}
测试结果
死信队列作为消息队列的一种可靠机制
消息过长
配置类
// 设置队列过期时间
@Bean
public Queue ttlQueue() {
//设置队列参数
Map<String, Object> args = new HashMap<>();
//x-message-ttl: 表示过期时间
args.put("x-message-ttl", 5000);
//队列容纳最大长度
args.put("x-max-length", 5);
//绑定死信交换机
args.put("x-dead-letter-exchange","dead_direct_exchange");
//绑定死信key direct模式下需要配置
args.put("x-dead-letter-routing-key","dead");
return new Queue("ttl_direct_queue", true, false, false, args);
}
结果
队列只能容纳5条消息,多余的会转移到死信队列