死信队列
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<String, Object> 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<String, Object> args = new HashMap<String, Object>();
args.put("x-delayed-type", "direct");
channel.exchangeDeclare(交换机名称, "x-delayed-message", true, false, args);
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。