1.設置隊列消息過期時間
@Bean //注入正常交換器
public FanoutExchange normalExchange() {
return new FanoutExchange("NORMAL_EXCHANGE", true, false);
}
@Bean //注入正常隊列
public Queue normalQueue() {
Map<String, Object> params = new HashMap<>();
//隊列裏面的死信會轉發到DLX_EXCHANGE交換器上
params.put("x-dead-letter-exchange", "DLX_EXCHANGE");
//隊列中的消息超過60秒沒被消費,則成爲死信
//(這個屬性設置要第一次聲明隊列時纔有用,如果隊列一開始已存在且沒有這個屬性,則要刪掉隊列再重新聲明纔有用)
params.put("x-message-ttl", 60 * 1000);
return new Queue("MY_QUEUE", true, false, false, params);
}
@Bean //交換機與隊列進行綁定
public Binding dlxQueueBind(@Qualifier("normalQueue") Queue queue, @Qualifier("normalExchange") FanoutExchange exchange) {
return BindingBuilder.bind(queue).to(exchange);
}
2.設置單個消息過期時間
MessageProperties properties = new MessageProperties();
//該消息在隊列中超過60秒沒被消費,則成爲死信
properties.setExpiration(60 * 1000 + "");
Message message = MessageBuilder
.withBody("abc".getBody())
.andProperties(properties)
.build();
rabbitTemplate.convertAndSend("NORMAL_EXCHANGE", "NORMAL_ROUTINGKEY", message);
無論用以上哪種方法,都是等消息到達隊列頭即將要被消費時,纔會判斷是否過期。
所以對於方法2,可能隊列中某個消息已經過期了,但它還沒到達隊列頭部,因此還會停留在隊列中。
這種只判斷隊列頭是否過期的方法的優勢是,不用時刻掃描整個隊列的所有消息去判斷哪個過期,這樣非常耗資源。