rabbitMq-TTL、DLX实现延时队列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014045580/article/details/72637710

在第一篇rabbitMq的交换机博客里穿插了许多api介绍,在声明队列时可以指定x-message-ttl消息过期时间、x-dead-letter-exchange死信交换机和x-dead-letter-routing-key死信路由键,在发送消息时也可以指定消息的过期时间。rabbitMq没有提供延时队列功能,但是我们可以利用TTL(过期时间)和(DLX)死信交换机来实现延时队列功能。

基于队列和基于消息的TTL

TTL是time to live 的简称,顾名思义指的是消息的存活时间。rabbitMq可以从两种维度设置消息过期时间,分别是队列和消息本身。

队列消息过期时间-Per-Queue Message TTL:
通过设置队列的x-message-ttl参数来设置指定队列上消息的存活时间,其值是一个非负整数,单位为微秒。不同队列的过期时间互相之间没有影响,即使是对于同一条消息。队列中的消息存在队列中的时间超过过期时间则成为死信。

       Map<String, Object> args = new HashMap<String, Object>();
      args.put("x-message-ttl", 60000);
      channel.queueDeclare("myqueue", false, false, false, args);

消息过期时间-Per-Message TTL:
发送消息时可以单独指定每条消息的TTL,通过设置AMQP.Properties的expiration属性可以指定消息的过期时间。
注意当队列过期时间和消息过期时间都存在时,取两者中较短的时间。

byte[] messageBodyBytes = "Hello, world!".getBytes();
AMQP.BasicProperties properties = new AMQP.BasicProperties();
properties.setExpiration("60000");
channel.basicPublish("my-exchange", "routing-key", properties, messageBodyBytes);

死信交换机DLX

队列中的消息在以下三种情况下会变成死信
(1)消息被拒绝(basic.reject 或者 basic.nack),并且requeue=false;
(2)消息的过期时间到期了;
(3)队列长度限制超过了。
当队列中的消息成为死信以后,如果队列设置了DLX那么消息会被发送到DLX。通过x-dead-letter-exchange设置DLX,通过这个x-dead-letter-routing-key设置消息发送到DLX所用的routing-key,如果不设置默认使用消息本身的routing-key;

channel.exchangeDeclare("some.exchange.name", "direct");

Map<String, Object> args = new HashMap<String, Object>();
args.put("x-dead-letter-exchange", "some.exchange.name");
args.put("x-dead-letter-routing-key", "some-routing-key");
channel.queueDeclare("myqueue", false, false, false, args);

延时队列

现在我们知道了,我们既可以控制消息在一段时间后变成死信,又可以控制变成死信的消息被路由到某一个指定的交换机,结合二者,其实就可以实现一个延时队列。消息的过期时间又两种设置方法,延时队列对应的也有两种实现思路。如下图:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/u014045580/article/details/72637710