rabbitmq(中)(死信队列和延时队列)

死信队列 ttl ttl(time to live),消息存活时间
RabbitMQ支持两种ttl设置:

  • 整个队列进行配置ttl,所有被投递到该队列的消息都最多不会存活超过N
  • 单独消息进行配置ttl
如果同时配置了队列的TTL和消息的TTL,那么较小的那个值将会被使用。
死信消息 以下3种情况消息出现死信:
  • 消费者拒收消息(basic.reject/ basic.nack) ,并且没有重新入队 requeue=false
  • 消息在队列中未被消费,且超过队列或者消息本身的过期时间TTL(time-to-live)
  • 队列的消息长度达到极限
出现死信时,此队列绑定了死信交换机,死信消息会路由到死信队列中
死信交换机DLX 死信交换机和死信队列的声明,与普通的交换机、队列没有任何差别
不过是在普通队列声明时指定了如下属性:
Map args = new HashMap<>(3); //消息过期后,进入到死信交换机 args.put("x-dead-letter-exchange", "指定的死信交换机的名称");

消息进入死信队列后,我们依然可以对监听,做一些特殊处理。
比如:订单在十分钟之内未支付则自动取消。
我们可以设置队列的ttl为10min,待支付订单的id作为消息放入其中;同时绑定死信队列,然后消费者监听死信队列。
这样待消息超时时,消息会进入死信队列并被消费者获取;消费者完成订单取消逻辑即可。
延时队列 再看ttl 如果设置了队列的ttl属性,那么一旦消息过期,就会被队列丢弃;而消息层面的ttl,则有些玄妙。
比如一条消息的ttl很短,但前一条消息ttl却很长——这种情况即使本消息过期了也不会马上丢弃。也就是说,消息层面的超时时间,会受队列的消息堆积情况影响。
那么不固定的延时情况,通过死信队列实现会有问题。
比如这个需求:预定会议室成功后开会前10分钟通知。
  • 采用在队列上设置ttl的方式,由于时间的不固定,必然会产生超多队列
  • 采用在消息上设置ttl的方式,由于消息堆积通知会不准,甚至无法通知
那如何解决这个问题呢?安装rabbitmq_delayed_message_exchange插件即可。
生产者关键代码:
Map args = new HashMap(); args.put("x-delayed-type", "direct"); channel.exchangeDeclare(交换机名称, "x-delayed-message", true, false, args);

附录 【rabbitmq(中)(死信队列和延时队列)】P6-P7知识合辑

    推荐阅读