一、为队列设置消息 TTL
TTL 是 Time-To-Live 的缩写,指的是存活时间,RabbitMQ 可以为每个队列设置消息的超时时间。
代码中声明如下:
只要给队列设置 x-message-ttl 参数,就设定了该队列所有消息的存活时间,时间单位是毫秒,值必须大于等于 0
RabbitMQ 保证死消息(在队列中的时间超过设定的 TTL 时间)不会被消费者获得,同时会尽快删除死的消费者。
消息不会在消费者的缓冲区中过期,也就是说,只要队列在消息过期前将消息推送给消费者,消费者就一定能处理到这条消息。
重新入队(例如被取消确认或者信道关闭或拒绝并重新入队)的消息的过期时间保留初始值,即不刷新过期时间。
二、为单条消息设置 TTL
也可以为单条消息设置消息存活时间。
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
builder.expiration("3000");
AMQP.BasicProperties build = builder.build();
当前版本采用的是 Builder 模式创建实例,在此我们通过 expration 的值设置消息的存活时间为 3 秒。
当队列消息的 TTL 和消息 TTL 都被设置,时间短的 TTL 设置生效。
为消息设置 TTL 有一个问题:RabbitMQ 只对处于队头的消息判断是否过期(即不会扫描队列),所以,很可能队列中已存在死消息,但是队列并不知情。这会影响队列统计数据的正确性,妨碍队列及时释放资源。
向队列中添加 110 条消息,前 10 条为没有超时时间的消息,后 100 条为设置了超时时间的消息
证明:如果队头为没有设置超时时间的消息,即使后面消息已经超时也不会被移除队列。
三、设置队列的 TTL(队列超时时间)
编程时设置方式
队列未被使用是指未发生如下行为:
- 队列没有被重新申明
- 没有 basicGet 操作发生
- 没有 Consumer 连接在队列上(哪怕队列一直没有消息)
特别的:就算一直有消息进入队列,也不算队列在被使用。
RabbitMQ 能保证未被使用的队列一定不会在指定的时间内内删除,但是不能保证能及时删除,只能保证在 RabbitMQ 重启后一定已经删除。
过期时间单位也是毫秒,但是与消息 TTL 不同在于 队列 TTL 值必须大于零。