RabbitMQ-延遲隊列代碼實踐

延遲隊列的本質用的到時死信,如下情況下消息會變爲死信
1 nack\color{#FF0000}{被拒絕、nack並且沒有重新入隊的消息}
2 消息過期
3 隊列達到了最大長度。
成爲死信的消息可以進入死信交換機,然後進入另外一個隊列中。

兩個交換器和隊列如下
在這裏插入圖片描述

//--------------------------死信隊列測試------------------

    public static final String NORMAL_QUEUE_NAME="queue.normal";

    public static final String NORMAL_EXCHANGE_NAME="exchange.normal";

    public static final String NORMAL_ROUTING_KEY ="normal.routing.key";

    @Bean
    public Queue normalQueue(){
        //設置死信隊列
        Map<String,Object> arguments=new HashMap<>();
        arguments.put("x-dead-letter-exchange",DEAD_EXCHANGE_NAME);
        arguments.put("x-dead-letter-routing-key",DEAD_LETTER_ROUTING_KEY);
        //設置過期時間爲10秒
        arguments.put("x-message-ttl",10000);
       return new Queue(NORMAL_QUEUE_NAME, true, false, false,arguments);
    }

    @Bean
    public DirectExchange normalExchange(){
        return new DirectExchange(NORMAL_EXCHANGE_NAME,true,false);
    }

    @Bean
    public Binding normalExchangeBindQueue(){
        return BindingBuilder.bind(normalQueue())
                .to(normalExchange())
                .with(NORMAL_ROUTING_KEY);
    }

    public static final String DEAD_LETTER_ROUTING_KEY ="dead.letter.test";

    public static final String DEAD_EXCHANGE_NAME="exchange.dlx";

    public static final String DEAD_QUEUE_NAME="queue.dlx";

    @Bean
    public Queue deadQueue(){
        return new Queue(DEAD_QUEUE_NAME);
    }

    @Bean
    public DirectExchange deadExchange(){
        return new DirectExchange(DEAD_EXCHANGE_NAME,true,false);
    }

    /**
     * 死信隊列與交換器綁定
     * @return
     */
    @Bean
    public Binding deadExchangeBindQueue(){
        return BindingBuilder.bind(deadQueue())
                .to(deadExchange())
                .with(DEAD_LETTER_ROUTING_KEY);
    }

發送

@Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMsg(){
        //發送Map對象
        Map<String,Object> map=new HashMap<>();
        map.put("id",1);
        map.put("username","張三");
        map.put("password","123");

        //設置消息唯一id
        CorrelationData correlationData=new CorrelationData();
        correlationData.setId(1+"");
        logger.info("發送時間{}",System.currentTimeMillis());
        rabbitTemplate.convertAndSend(RabbitMQConfig.NORMAL_EXCHANGE_NAME,//exchange
                RabbitMQConfig.NORMAL_ROUTING_KEY,//rountingKey
                map,//
                correlationData);
    }

接收方:

/**
     * 死信隊列
     * @param user
     * @param headers
     * @param channel
     * @throws IOException
     */
    @RabbitListener(queues = "queue.dlx")
    @RabbitHandler
    public void onUserInfoMessage(@Payload Map user,
                                  @Headers Map<String, Object> headers, Channel channel) throws IOException {
        //消費者操作
        logger.info("接收到的消息【{}】", user.toString());
        logger.info("接受到消息的時間{}",System.currentTimeMillis());

        //確認簽收
        Long deliveryTag = (Long) headers.get(AmqpHeaders.DELIVERY_TAG);
        channel.basicAck(deliveryTag, false);
    }

控制檯打印的兩個時間正好相差10秒。

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