RabbitMQ延時佇列的使用

DanceDonkey發表於2020-11-05

延時佇列概述

通過給一個普通的佇列設定一些引數,死信交換機,死信路由,以及佇列過期時間,注意,這個佇列不能讓任何消費者監聽,然後我們將訊息統一發往這個佇列,當這個佇列中的訊息過期後,就會根據我們指定的死信交換機和死信路由去往新的佇列,我們的程式可以監聽這個佇列,一旦這個佇列監聽到訊息了,則一定是延時佇列中過期的訊息。

  • 流程圖如下

在這裡插入圖片描述

延時佇列測試使用

  • 引入AMQP的依賴
 		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
  • 編寫一個配置類,給容器中注入一些bean,當容器啟動時,會自定根據這些bean去rabbit伺服器建立響應佇列與交換機。
@Slf4j
@Configuration
public class RabbitConfig {

    @Bean
    public MessageConverter messageConverter(){
        return new Jackson2JsonMessageConverter();
    }

    /**
     * 建立延時佇列
     */
    @Bean
    public Queue orderDelayQueue(){
        Map<String,Object> map = new HashMap<>();
        //訊息過期後交給這個交換機處理
        map.put("x-dead-letter-exchange","order-event-exchange");
        //訊息過期後交給上面的交換機,該交換機再根據這個路由鍵轉發給那個處理訊息的佇列
        map.put("x-dead-letter-routing-key","order.release.order");
        //設定佇列的過期時間
        map.put("x-message-ttl",60000);
        Queue queue = new Queue("order.delay.queue",true,false,
                false,map);
        return queue;
    }

    /**
     * 當延時佇列中的訊息過期時將訊息發往這個佇列
     */
    @Bean
    public Queue orderReleaseOrderQueue(){
        Queue queue = new Queue("order.release.order.queue",true,false,
                false,null);
        return queue;
    }

    /**
     * 交換機,這個交換機同時繫結延時佇列和訂單釋放佇列,需要根據不同的routing-key來轉發到不同的佇列
     * 所以我們選擇用Topic型別交換機
     */
    @Bean
    public Exchange orderEventExchange(){
        TopicExchange exchange = new TopicExchange(
                "order-event-exchange",
                true,
                false,
                null
        )    ;
        return exchange;
    }

    /**
     * 將交換機和佇列進行繫結,同時可以繫結兩個佇列
     */
    @Bean
    public Binding orderCreateOrder(){
        return new Binding(
                "order.delay.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.create.order", //延時佇列繫結的路由鍵,建立訂單時根據這個路由鍵傳送到延時佇列
                null
        );
    }

    @Bean
    public Binding orderReleaseOrder(){
        return new Binding(
                "order.release.order.queue",
                Binding.DestinationType.QUEUE,
                "order-event-exchange",
                "order.release.order", //消費佇列繫結的路由鍵,延時佇列中的訊息失效後根據這個路由鍵傳送給響應的佇列
                null
        );
    }

    /**
     * 測試監聽佇列,監聽的是延時佇列過期後的處理佇列
     */
    @RabbitListener(queues = "order.release.order.queue")
    public void listener(Message message, OrderDTO orderDTO, Channel channel){
        log.info("收到過期的訂單資訊,準備關閉訂單,{}",orderDTO);
    }
}
  • 其中我們在建立延時佇列時,傳遞了一個Map,這個map就是指定了我們延時佇列的一些屬性資訊。

登入rabbit伺服器檢視,order.delay.queue這個佇列確實多了這三個屬性。
在這裡插入圖片描述

相關文章