Rabbitmq之消息過期設置

消息的過期時間

目前有兩種方法可以設置消息的 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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章