RabbitMQ 遅延メッセージの実装 - デッドレターメッセージ

1. 実施原則

キュー ttl + デッド レター交換
の簡単な説明: 2 つのキューを使用します。1 つのキューはメッセージを消費せずに受信します。指定された時間待機した後、メッセージは消滅し、その後キューにバインドされたデッド レター交換がメッセージを別のキューに再度ルーティングして提供します。ビジネス消費。
ttl: x-message-ttl メッセージの生存時間

2. 実現

  1. スイッチとキューを宣言する

@SpringBootConfiguration
public class RabbitDelayConfig {
    
    
    /**
     * 死信队列
     */
    public static final String DEAD_QUEUE = "dead.queue";
    /**
     * 延时队列
     */
    public static final String DELAY_QUEUE = "delay.queue";
    /**
     * 死信交换机
     */
    public static final String DEAD_EXCHANGE = "dead.exchange";
    /**
     * 原交换机
     */
    public static final String DELAY_EXCHANGE = "delay.exchange";
    /**
     * 声明延时队列(生产者投递消息)
     * 
     *
     * @return
     */
    @Bean
    public Queue getDelayQueue() {
    
    
        //参数一:队列名称;参数二:队列中消息存活时间(单位ms);参数三:消息过期转发的死信交换机;参数四:死信队列和死信交换机绑定的rootingKey
        Queue queue = QueueBuilder.durable(DELAY_QUEUE).ttl(10 * 1000).deadLetterExchange(DEAD_EXCHANGE).deadLetterRoutingKey("deadKey").build();
        return queue;
    }
    /**
     * 声明死信队列(接收过期转发消息)
     *
     * @return
     */
    @Bean
    public Queue getDeadQueue() {
    
    
        return new Queue(DEAD_QUEUE, true);

    }
    /**
     * 死信交换机(转发消息到死信队列)
     *
     * @return
     */
    @Bean
    public DirectExchange deadExchange() {
    
    
        DirectExchange exchange = new DirectExchange(DEAD_EXCHANGE, true, false);
        return exchange;
    }

    /**
     * 原交换机(投递消息到延时队列)
     *
     * @return
     */
    @Bean
    public DirectExchange delayExchange() {
    
    
        DirectExchange exchange = new DirectExchange(DELAY_EXCHANGE, true, false);
        return exchange;
    }

    /**
     * 绑定死信队列和死信交换机
     *
     * @return
     */
    @Bean
    public Binding bindDeadExchangeQueue() {
    
    
        Binding binding = BindingBuilder.bind(getDeadQueue()).to(deadExchange()).with("deadKey");
        return binding;
    }

    /**
     * 绑定延时队列和原交换机
     *
     * @return
     */
    @Bean
    public Binding bindDelayExchangeQueue() {
    
    
        Binding binding = BindingBuilder.bind(getDelayQueue()).to(delayExchange()).with("delay-routingKey");
        return binding;
    }
}
  1. プロデューサーの作成
@SpringBootTest
@RunWith(SpringRunner.class)
public class DelayMqTest {
    
    
    @Resource
    private RabbitTemplate rabbitTemplate;

    @Test
    public void send() {
    
    
        rabbitTemplate.convertAndSend(RabbitDelayConfig.DELAY_EXCHANGE, "delay-routingKey", "延时消息");
        System.out.println("发送消息时间:" + System.currentTimeMillis());
    }
  1. コンシューマを作成します (リスニング キューはデッド レター キューです)。
@Component
public class DelayConsumer {
    
    
    @RabbitListener(queues = RabbitDelayConfig.DEAD_QUEUE)
    public void listenDead1(String message) {
    
    
        System.out.println("接收时间:" + System.currentTimeMillis());
        System.out.println("消费者一接收消息:" + message);
    }

}

結果:
ここに画像の説明を挿入します
ここに画像の説明を挿入します
メッセージの受信時間とメッセージの送信時間は、設定したメッセージ生存時間と基本的に一致していることがわかります。

3. さらに

メッセージの生存時間を設定するには 2 つの方法があります:
1. 遅延キューの作成時に設定します。ここで設定すると、キュー内のすべてのメッセージの生存時間が同じになります。

    @Bean
    public Queue getDelayQueue() {
    
    
        Queue queue = QueueBuilder.durable(DELAY_QUEUE).ttl(10 * 1000).deadLetterExchange(DEAD_EXCHANGE).deadLetterRoutingKey("deadKey").build();
        return queue;
    }

2. メッセージ送信時に設定します。ここで設定すると、キュー内のメッセージの生存時間が異なります。

    @Test
    public void send1() {
    
    
        rabbitTemplate.convertAndSend(RabbitDelayConfig.DELAY_EXCHANGE, "delay-routingKey", "延时消息1111", message -> {
    
    
            message.getMessageProperties().setExpiration(20 * 1000 + "");
            return message;
        });
        System.out.println("发送消息时间:" + System.currentTimeMillis());
    }

特に、両方にメッセージ生存時間が設定されている場合、実際のメッセージ生存時間はメッセージの送信時に指定されます。上記のコードでは、実際のメッセージ生存時間は 20000 ミリ秒です。

おすすめ

転載: blog.csdn.net/asasasasasawqwqwqw/article/details/131236865
おすすめ