乐趣区

关于java: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<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);

附录

P6-P7 常识合辑

退出移动版