1.死信
死信
也就是dead message,可以简单理解为无法被成功消费对消息。消息变成死信消息大概有下面几种情况
- 消息TTL过期(消息或队列设置了过期时间)
- 队列达到最大长度
- 消息被拒绝(basic.reject / basic.nack),并且requeue = false禁止重入
2.死信队列与死信交换机
- 死信交换机,用户转发死信消息(dead message)的交换机,并没有具体的`死信类型``的交换机,而且逻辑上定义一个死信交换机。可以在配置消息队列时候,绑定死信交换机,死信消息通过该交换机转发到死信队列。
- 死信队列,用于接受死信消息的队列,他不是一个具体的队列类型。是我们业务逻辑上定义一个
死信队列
,
3.应用场景
3.1死信队列+TTL(time-to-live) 实现延迟队列
- 订单过期场景可以用上述方案来模拟:下单后会先到order队列,当到达过去时间后可以转dead队列进行下一步处理。
3.2 配置死信队列和死信交换机
/**
* 死信队列、死信交换机
* @return
*/
@Bean
public Queue testQueueDead() {
return new Queue("my.order.dead.queue");
}
@Bean
public DirectExchange myExchangeDead() {
return new DirectExchange("my.order.dead.exchange");
}
@Bean
public Binding bindingDead() {
return BindingBuilder.bind(testQueueDead()).to(myExchangeDead()).with("my.key");
}
3.3业务队列绑定死信交互机
@Bean
public Queue testQueueOrder() {
Map<String, Object> args = new HashMap<>();
/**
* x-dead-letter-exchange , value = '死信交换机的名字'
* x-dead-letter-routing-key value='路由key'
* 1.如果是direct 的交换机,key要相同
* //args.put("x-message-ttl",60000); 设置整个队列的过期时间
*/
args.put("x-dead-letter-exchange","my.order.dead.exchange");
args.put("x-dead-letter-routing-key","my.key");
return new Queue("my.amqpAdmin.queue.order",true,false,false, args);
}
@Bean
public DirectExchange myExchangeOrder() {
return new DirectExchange("my.direct.order");
}
@Bean
public Binding bindingOrder() {
return BindingBuilder.bind(testQueueOrder()).to(myExchangeOrder()).with("my.key");
}
3.4 发送带有过期时间到消息
amqpTemplate.convertAndSend("my.direct.order","my.key",employee,message->{
message.getMessageProperties().setDeliveryMode(MessageDeliveryMode.PERSISTENT);
message.getMessageProperties().setExpiration("50000");
return message;
})
在创建队列的时候也可以设置整个队列的过期时间