文章参考:Rabbit实战指南
过期时间(TTL)
TTL,Time to Live的简称,即过期时间,RabbitMQ可以对消息和队列设置TTL。
-
设置消息的TTL
目前有两种方法可以设置消息的TTL。第一种通过队列属性设置,队列中所有消息都有相同的过期时间。第二种方法是对消息本身进行单独设置,每条消息的TTL可以不同。如果两中方法一起使用,TTL以两者之间较小的值为准。消息在队列中的生存时间一旦超过TTL值时,就会变成“死信”,消费者无法再收到信息(这点不是绝对的)。
通过队列属性设置消息TTL的方法在
channel.queueDeclare
方法中加入x-message-ttl参数实现,参数单位是毫秒。Map<String,Object> args = new HashMap<>(); args.put("x-message-ttl",6000); channel.queueDeclare(queueName,durable,exclusive,autoDelete,args);
如果不设置TTL,则表示此消息不会过期;如果将TTL设置为0,表示除非此时可以直接将消息投递到消费者,否则该消息会被立即丢弃,这个特性可以部分代替RabbitMQ3.0之前的immediate参数,之所以代替部分是因为immediate参数在投递失败会用
Basic.Return
将消息返回(这个消息可以使用死信队列来实现)。 针对每条信息设置TTL的方法是在
channel.basicPublish
方法中加入expiration的属性参数,单位为毫秒。关键代码如下:
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperteies.Builder(); builder.deliveryMode(2);//持久化消息 bulider.expiration("60000");//设置TTL=60000ms AMQP.BasicProperties properties = builder.build(); channel.basicPublish(exchangeName,routingKey,mandatory,properties,"ttlTestMessage".getBytes());
也可以使用第二种方式
AMQP.BasicProperties properties = new AMQP.BasicProperties(); properties.setDeliveryMode(2); properties.setExpiration("60000"); channel.basicPublish(exchangeName,routingKey,mandatory,properties,"ttlTestMessage".getBytes());
对于第一种设置队列 TTL 属性的方法,一旦消息过期,就会从队列中抹去,而第二种方法中,即使消息过期,也不会马上从队列中抹去,因为每天消息是否过期是在即将投递到消费者之前判定的。
-
设置队列的TTL
通过
channel.queueDeclare
方法中的x-expires参数可以控制队列被自动删除前处于未使用状态的时间。未使用的意思是队列上没有任何的消费者,队列也没有被重新声明,并且在过期时间段内也未调用过Basic,Get
命令。 设置队列里的TTL可以应用于类似RPC方式的回复队列,在RPC中,许多队列会被创建出来,但是却是未被使用的。
RabbitMQ会确保在过期时间到达后将队列删除,但是不保证删除的动作有多及时。在RabbitMQ重启后,持久化的队列的过期时间会被重新计算。
用于表示过期时间的x-expires参数以毫秒为单位,并且服从和x-message-ttl一样的约束条件,不过不能设置为0。比如改参数设置为1000,则表示该队列如果在1秒钟内未使用则会被删除。
演示创建了一个过期时间为30分钟的队列:
Map<String,Object> args = new HashMap<String,Object>(); args.put("x-expires",180000); channel.queueDeclare("myqueue",false,false,false,args);
网友评论