RabbitMQ 死信队列的使用
死信队列
DLX 死信队列。有以下几种情况,消息会进入到死信队列中:
-
消息过期 消息被拒绝 队列达到最大长度
实现的逻辑就是:也是创建一个交换机,就暂时叫它死信交换机,然后再创建一个死信队列,死信交换机和死信队列进行绑定。
当设置了ttl的队列中消息过期后就会把消息发送至我们的死信交换机,死信交换机再存入死信队列中,以后肯定还会有一个死信消费者来处理死信队列中的消息的。其实这还是一个提供者–>交换机—>队列---->消费者的过程。
问题是我们怎么让ttl队列过期后的消息发送至死信交换机中?
首先创建死信交换机、死信队列、绑定关系
/** * @author hs * @date 2021/06/29 */ @Configuration public class DeadConfiguration { @Bean public DirectExchange deadDirectExchange(){ return new DirectExchange("dead_direct_exchange"); } @Bean public Queue deadQueue(){ return new Queue("dead.direct.queue",true); } @Bean public Binding deadBinding(){ return BindingBuilder.bind(deadQueue()).to(deadDirectExchange()).with("dead"); } }
然后进行ttl队列和死信交换机进行绑定关系
@Bean public Queue queueTtl(){ //定义一个ttl队列 //定义一个map集合存放参数 Map<String,Object> arguments = new HashMap<>(); // 这里的key参数需要从web图形化界面中获得 arguments.put("x-message-ttl",5000); //设置死信交换机 map的key要从图形化界面获取 value是死信交换名 arguments.put("x-dead-letter-exchange","dead_direct_exchange"); // 因为我这个死信交换机采用的是direct模式 所有需要加一个路由key 但如果采用的是fanout模式 就不需要下面的语句 arguments.put("x-dead-letter-routing-key","dead"); return new Queue("ttl.direct.queue",true,false,false,arguments); }
这里运行会报错,原因是这个设置了ttl的队列我之前就创建了,然后我刚刚有新增了两行代码加了些参数,该队列是不会及时变更的,需要删除ttl队列,然后再重新创建该队列。
但是在真实开发中,在线上高速运转时不能直接删除队列,需要重新改个名字,创建新ttl队列,把消息提供方改为新的队列,而不要直接去删除原来的队列。
现在再运行就会发现,ttl.direct.queue队列中的消息过了几秒就消失了,然后过了一会儿就出现在了dead.direct.queue队列中了。
上面也提到了队列超过能存放消息的最大长度后,消息也会转入死信队列。设置队列的最大长度如下所示: 代码的实现就只是在map集合中加一个这个参数x-max-length
上一篇:
通过多线程提高代码的执行效率例子