1. 简介
1.1 DLX简介
DLX: Dead-Letter-Exchange 死信交换器,死信邮箱
当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。
如下图所示:
其实死信队列就是一个普通的交换机,有些队列的消息成为死信后,(比如过期了或者队列满了)这些死信一般情况下是会被 RabbitMQ 清理的。但是你可以配置某个交换机为此队列的死信交换机,该队列的消息成为死信后会被重新发送到此 DLX 。怎么处理这个DLX中的死信就是看具体的业务场景了,DLX 中的信息可以被路由到新的队列。
2.2 出现死信的情况
- 队列长度到达限制,无法加入新的消息
- 消费者拒接消费消息,并且不重回队列。该信息会被清除并进入死信队列
- 原队列存在消息过期设置,消息到达超时时间未被消费
2.3 代码示例
死信队列可以定义单条消息和整个队列死信,分别是下方的2和4。
2.代码示例
以下定义了两个交换机,分别是普通交换机和死信交换机,定义了两个队列,分别是普通队列和死信队列。
@Configuration
public class RabbitConfig {
final static String exchangeNormalName = "exchange.dlx.normal";
final static String queueNormalName = "queue.dlx.normal";
final static String exchangeDeadName = "exchange.dlx.dead";
final static String queueDeadName = "queue.dlx.dead";
//正常交换机
@Bean
public DirectExchange normalExchange(){
return ExchangeBuilder.directExchange(exchangeNormalName).build();
}
//正常队列
@Bean
public Queue normalQueue(){
Map<String, Object> map = new HashMap<>();
map.put("x-message-ttl", 20000);//设置20s的过期时间
map.put("x-dead-letter-exchange", exchangeDeadName);//设置死信交换机名字
map.put("x-dead-letter-routing-key", "error");//设置死信交换机路由k
return QueueBuilder.durable(queueNormalName)
.withArguments(map)
.build();
}
@Bean
public Binding normalBinding(DirectExchange normalExchange, Queue normalQueue){
return BindingBuilder.bind(normalQueue).to(normalExchange).with("order");
}
//死信交换机
@Bean
public DirectExchange dlxExchange(){
return ExchangeBuilder.directExchange(exchangeDeadName).build();
}
//死信队列
@Bean
public Queue dlxQueue(){
return QueueBuilder.durable(queueDeadName).build();
}
@Bean
public Binding dlxBinding(DirectExchange dlxExchange, Queue dlxQueue){
return BindingBuilder.bind(dlxQueue).to(dlxExchange).with("error");
}
}
如上,设置普通交换机把过期内容放置到死信交换机中去。最重要的几行代码如下:
- map.put(“x-message-ttl”, 20000);//设置20s的过期时间
- map.put(“x-dead-letter-exchange”, exchangeDeadName);//设置死信交换机名字
- map.put(“x-dead-letter-routing-key”, “error”);//设置死信交换机路由key
3.测试结果
经过20s之后,如下,将普通队列的信息放入死信队列中
其中TTL代表x-message-ttl,DLX代表x-dead-letter-exchange,DLK代表x-dead-letter-routing-key
4.单条消息
上方是将整个队列设置过期时间,也可以将单条消息设置过期时间,即不给整个队列设置过期时间
//map.put("x-message-ttl", 20000);//设置20s的过期时间
map.put("x-dead-letter-exchange", exchangeDeadName);//设置死信交换机名字
map.put("x-dead-letter-routing-key", "error");//设置死信交换机路由k
而是在消息体中设置过期时间
@Component
@Slf4j
public class MessageService {
@Autowired
private RabbitTemplate rabbitTemplate;
public void senMsg() throws InterruptedException {
//定义消息
String msg="单条消息过期时间test";
MessageProperties messageProperties = new MessageProperties();
messageProperties.setExpiration("10000"); //10s
Message message= MessageBuilder.withBody(msg.getBytes()).andProperties(messageProperties).build();
//发消息
rabbitTemplate.convertAndSend("exchange.dlx.normal","order",message);
log.info("消息发送完毕,发送时间为:{}", new Date());
}
}
文章来源:https://www.toymoban.com/news/detail-716248.html
文章来源地址https://www.toymoban.com/news/detail-716248.html
到了这里,关于RabbitMQ-死信交换机和死信队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!