RabbitMQ 高階 - 過期時間 TTL

HuDu發表於2021-06-08

概述

過期時間 TTL 表示可以對訊息設定預期的時間,在這個時間內都可以被消費者接收穫取;過期後自動被刪除;RabbitMQ 可以對訊息和佇列 設定 TTL。目前有兩種方法可以設定

第一種方法是通過佇列屬性的設定,佇列中所有訊息多有相同的過期時間
第二種方法是對訊息單獨設定,每條訊息 TTL 可以不同
這兩種方式的區別在於通過佇列屬性設定的訊息是移到死信佇列中,而單獨訊息設定 TTL 是訊息自動消失。

如果上述兩種方法同時使用,則訊息的過期時間可以兩者之間 TTL 較小的哪個數值為準。訊息在佇列的生存時間一旦超過設定的 TTL 值,就稱為 dead message 被投遞到死信佇列,消費者將無法再收到該訊息。

設定佇列 TTL

配置類配置如下

@Configuration
public class TTLRabbitMqConfiguration {
    @Bean
    public DirectExchange ttlDirectExchange() {
        return new DirectExchange("ttl_direct_order_exchange",true,false);
    }

    @Bean
    public Queue directTtlQueue() {
        // 設定過期時間
        HashMap<String, Object> args = new HashMap<>();
        args.put("x-message-ttl",5000); // 這裡一定是一個int型別
        return new Queue("ttl.direct.queue",true,false,false,args);
    }

    @Bean
    public Binding ttlBinding() {
        return BindingBuilder.bind(directTtlQueue()).to(ttlDirectExchange()).with("ttl");
    }
}


public void makeOrderTtl(String userId,String productId,int num) {
  // 1:根據id查詢商品是否充足
  // 2:儲存訂單
  String orderId = UUID.randomUUID().toString();
  System.out.println("訂單生成成功:"+orderId);
  // 3:通過 MQ 來完成訊息的分發
  // 交換機,路由 key/queue 佇列名稱,訊息內容
  String exchangeName = "ttl_direct_order_exchange";
  String routingKey = "ttl";
  rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId);
}

測試程式碼

@Test
void testOrderTtl() {
    orderService.makeOrderTtl("1","1",12);
}

RabbitMQ 高階 - 過期時間 TTL

五秒過後資料自動消失

RabbitMQ 高階 - 過期時間 TTL

RabbitMQ 高階 - 過期時間 TTL

訊息設定過期時間

config 配置程式碼

@Configuration
public class TTLRabbitMqConfiguration {
    @Bean
    public DirectExchange ttlDirectExchange() {
        return new DirectExchange("ttl_direct_order_exchange",true,false);
    }

    @Bean
    public Queue directTtlQueue() {
        // 設定過期時間
        HashMap<String, Object> args = new HashMap<>();
        args.put("x-message-ttl",5000); // 這裡一定是一個int型別
        return new Queue("ttl.direct.queue",true,false,false,args);
    }

    @Bean
    public Queue directTtlMessageQueue() {
        return new Queue("ttl.message.direct.queue",true);
    }

    @Bean
    public Binding ttlBinding() {
        return BindingBuilder.bind(directTtlMessageQueue()).to(ttlDirectExchange()).with("ttlMessage");
    }

}

測試程式碼

public void makeOrderTtlMessage(String userId,String productId,int num) {
        // 1:根據id查詢商品是否充足
        // 2:儲存訂單
        String orderId = UUID.randomUUID().toString();
        System.out.println("訂單生成成功:"+orderId);
        // 3:通過 MQ 來完成訊息的分發
        // 交換機,路由 key/queue 佇列名稱,訊息內容
        String exchangeName = "ttl_direct_order_exchange";
        String routingKey = "ttlMessage";
        // 給訊息設定過期時間
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                // 設定過期時間
                message.getMessageProperties().setExpiration("5000");
                message.getMessageProperties().setContentEncoding("UTF-8");
                return message;
            }
        };
        rabbitTemplate.convertAndSend(exchangeName,routingKey,orderId,messagePostProcessor);
    }

@Test
void testOrderTtlMessage() {
  orderService.makeOrderTtlMessage("1","1",12);
}

五秒之後訊息自動過期消失

RabbitMQ 高階 - 過期時間 TTL

RabbitMQ 高階 - 過期時間 TTL

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章