RabbitMQ Queue中Arguments属性参数过期队列,过期消息,超时队列的声明
创建队列时指定参数
队列属性:x-message-ttl
可以控制被publish到queue中的message 被丢弃前能够存活的时间,当某个message在queue 存留的时间超过了配置的TTL值 我们就说该message“已死”。值得注意的是,当一个message被路由到多个queue中时,其可以在不同的时间死掉,或者可能有的不会出现死掉的情况。(在某个queue中的某个message的 死亡不会对相同message在其他queue中的生存状况产生影响)。
服务器会保证“死掉”的 message 将不会被包括在任何的 basic.get-ok 或 basic.deliver 方法中。更进一步,服务器将努力在 TTL 到期或到期后的短时间内处理掉该 message 。
Java代码:message在该queue的存过时间最大为60秒
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-message-ttl", 60000);
channel.queueDeclare("myqueue", false, false, false, args);
参数 x-message-ttl 的值 必须是非负 32 位整数 (0 <= n <= 2^32-1) ,以毫秒为单位表示 TTL 的值。这样,值 1000 表示存在于 queue 中的当前 message 将最多只存活 1 秒钟,除非其被投递到 consumer 上。实参可以是以下 AMQP 类型:short-short-int 、short-int 、long-int 或者 long-long-int 。
设置 x-message-ttl 为 0 将使得,在 message 在到达 queue 之后但尚未被立即投递到 consumer 的情况下,判定为过期。这种方式相当于 RabbitMQ server 在3.0.0以后不支持 basic.publish 中 immediate 标识情况下的等价实现。与 immediate 标帜方式不同的是,将不会有 basic.returns 命令的调用,但是在设置了 dead letter exchange 的情况下,这些 message 将被处理为 dead-lettered(详见下面的DLX) 。
消息属性:expiration
当同时指定了 queue 和 message 的 TTL 值(expiration),则两者中较小的那个才会起作用。
下面的 Java 示例 publish 了最多能在 queue 中存活 60 秒的 message :
byte[] messageBodyBytes = "Hello, world!".getBytes();
AMQP.BasicProperties properties = new AMQP.BasicProperties();
properties.setExpiration("60000");
channel.basicPublish("myexchange", "routingkey", properties, messageBodyBytes);
虽然 consumer 从来看不到过期的 message ,但是在过期 message 到达 queue 的头部时确实会被真正的丢弃(或者 dead-lettered )。当对每一个 queue 设置了 TTL 值时不会产生任何问题,因为过期的 message 总是会出现在 queue 的头部。当对每一条 message 设置了 TTL 时,过期的 message 可能会排队于未过期 message 的后面,直到这些消息被 consume 到或者过期了。在这种情况下,这些过期的 message 使用的资源将不会被释放,且会在 queue 统计信息中被计算进去(例如,queue 中存在的 message 的数量)。
对于第一种设置队列TTL属性的方法,一旦消息过期,就会从队列中抹去,而第二种方法里,即使消息过期,也不会马上从队列中抹去,因为每条消息是否过期时在即将投递到消费者之前判定的,为什么两者得处理方法不一致?因为第一种方法里,队列中已过期的消息肯定在队列头部,RabbitMQ只要定期从队头开始扫描是否有过期消息即可,而第二种方法里,每条消息的过期时间不同,如果要删除所有过期消息,势必要扫描整个队列,所以不如等到此消息即将被消费时再判定是否过期,如果过期,再进行删除。
队列属性:x-expires
x-expires参数控制queue被自动删除前可以处于未使用状态的时间。未使用的意思是queue上没有任何consumer, queue 没有被重新声明,并且在过期时间段内为调用过basic.get命令 。 该方法用于例如:RPC-style 的回复 queue,其中许多queue会被创建出来,但是却从未被使用。
服务器会确保在过期时间到达后queue被删除,但是不保证删除的动作有多么的及时,在服务器启动后,持久化的queue的超时时间将重新计算。
用于表示超时时间的x-expires参数值以毫秒为单位,并且服从和 x-message-ttl 一样的约束。且不能设置为0,所以如果该参数设置为1000,则表示该queue 如果在1秒钟只能未被使用则会被删除。
下面Java声明队列为,30分钟不使用的情况下会被判定为超时。
Map<String, Object> args = new HashMap<String, Object>();
args.put("x-expires", 1800000);
channel.queueDeclare("myqueue", false, false, false, args);