消息TTL
方式1:通过队列属性设置,队列中所有消息,都有相同的过期时间。
Map<String , Object> argss =new HashMap<String , Object>() ;
argss .put ("x-message-ttl" , 6000); // 单位是毫秒
channel.queueDeclare(queueName , durable , exclusive , autoDelete , argss) ;
方式2:第二种方法是对消息本身进行单独设置,每条消息的 TTL 可以不同
AMQP.BasicProperties.Builder builder= new AMQP.BasicProperties.Builder() ;
builder.deliveryMode(2); // 持久化消息
builder.expiration("6000");// 设置 TTL=60000ms
AMQP.BasicProperties properties= builder. build() ;
channel.basicPublish(exchangeName , routingKey , mandatory , properties, "ttlTestMessage".getBytes());
如果两种方法都使用,则消息的TTL以两者较小的那个数值为准。
消息在队列中的生存时一旦超过设置 TTL 值时,就会变成“死信”( Dead Message ),消费者将无法再收到该消息
对于第一种设置队列TTL 属性的方法,一旦消息过期,就会从队列中抹去,而在第二种方法中,即使消息过期,也不会马上从队列中抹去,因为每条消息是否过期是在即将投递到消费者之前判定的。
为啥两种处理方式不一样?
rabbitmq出于性能考虑,第一种方法里,队列中已过期的消息肯定在队列头部,RabbiMQ 只要定期从队头开始扫描是否有过期的消息即可。而第二种方法里,每条消息的过期时间不同,如果要删除所有过期消息势必要扫描整个队列,所以不如等到此消息即将被消费时再判定是否过期,如果过期再进行删除即可。