消息的過期時間
目前有兩種方法可以設置消息的 TTL 。第一種方法是通過隊列屬性設置,隊列中所有消息都有相同的過期時間。第二種方法是對消息本身進行單獨設置,每條消息的TTL可以不同。如果兩種方法一起使用,則消息的TTL以兩者之間較小的那個數值爲準。
對於第一種設置隊列屬性的方法,一旦消息過期,就會從隊列中抹去,而在第二種方法中,即使消息過期,也不會馬上從隊列中抹去,因爲每條消息是否過期是在即將投遞到消費者之前判定的。
爲什麼這兩種方法處理的方式不一樣?
因爲第一種方法裏,隊列中己過期的消息肯定在隊列頭部,RabbitMQ只要定期從隊頭開始掃描是否有過期的消息即可。而第二種方法裏,每條消
息的過期時間不同,如果要刪除所有過期消息勢必要掃描整個隊列,所以不如等到此消息即將被消費時再判定是否過期,如果過期再進行刪除即可。
1、聲明交換機
/**
* 1、聲明交換機
*/
@Test
public void decalreExchange() throws Exception {
String exchange = "hello_ttl";
// 獲取到連接
Connection connection = ConnectionUtil.getConnection();
// 獲取通道
Channel channel = connection.createChannel();
// 聲明exchange,指定類型爲direct
channel.exchangeDeclare(exchange, BuiltinExchangeType.DIRECT,true,false,false,new HashMap<>());
}
2、這裏聲明瞭兩個隊列,hello_ttl_c1給隊列設置了消息過期時間,hello_ttl_c2沒有設置。
/**
* 2、聲明隊列並綁定到交換機
*/
@Test
public void decalreQueueAndBind() throws Exception {
String exchange = "hello_ttl";
// 獲取到連接
Connection connection = ConnectionUtil.getConnection();
// 獲取通道
Channel channel = connection.createChannel();
//將隊列hello_ttl_c1 綁定到交換機hello_ttl上
String queueName1 = "hello_ttl_c1";
Map<String, Object> argss = new HashMap<String , Object>();
argss.put("x-message-ttl" , 30*1000);//設置隊列裏消息的ttl的時間30s
// 聲明隊列
channel.queueDeclare(queueName1, true, false, false, argss);
// 綁定隊列到交換機
channel.queueBind(queueName1, exchange, "aaa");
//隊列hello_ttl_c2 這個是爲了測試通過發送時設置ttl
String queueName2 = "hello_ttl_c2";
// 聲明隊列
channel.queueDeclare(queueName2, true, false, false, null);
// 綁定隊列到交換機
channel.queueBind(queueName2, exchange, "bbb");
}
可以看出隊列上的TTL屬性,D是聲明隊列durable設置爲true,表示隊列是持久化的。
3、測試設置過期時間的隊列
/**
* 測試隊列設置的ttl
* @throws Exception
*/
@Test
public void sendMessage1() throws Exception {
String exchange = "hello_ttl";
// 獲取到連接
Connection connection = ConnectionUtil.getConnection();
// 獲取通道
Channel channel = connection.createChannel();
// 消息內容
String message = "Less is more";
channel.basicPublish(exchange, "aaa", null, message.getBytes());
log.debug("Producer send message:{}",message);
channel.close();
connection.close();
}
30s 後,可以看到該消息被刪除
4、測試發送時設置ttl
/**
* 測試消息發送時設置ttl
* @throws Exception
*/
@Test
public void sendMessage2() throws Exception {
String exchange = "hello_ttl";
// 獲取到連接
Connection connection = ConnectionUtil.getConnection();
// 獲取通道
Channel channel = connection.createChannel();
// 消息內容
String message = "Less is more";
AMQP.BasicProperties.Builder builder = new AMQP.BasicProperties.Builder();
builder.deliveryMode(2); //DeliveryMode等於2就說明這個消息是persistent的。1是默認,不是持久的。
builder.expiration("30000");// 設置TTL=30000ms
AMQP.BasicProperties properties = builder. build() ;
channel.basicPublish(exchange, "bbb", properties, message.getBytes());
log.debug("Producer send message:{}",message);
channel.close();
connection.close();
}
大約30s後,消息也被刪除
詳細源碼地址
https://github.com/suzhe2018/rabbitmq-item
轉載於:https://my.oschina.net/suzheworld/blog/3003095