Springboot 2.x intègre Rabbitmq pour réaliser une consommation différée

Préface

Par exemple, lorsque nous utilisons mq, nous ne voulons pas recevoir le message immédiatement. Par exemple, nous pouvons interroger la commande après 3 minutes. À ce stade, nous devons utiliser le message différé pour envoyer.

Comment RabbitMQ implémente-t-il les files d'attente tardives?

Le protocole AMQP et la file d'attente RabbitMQ elle-même ne prennent pas directement en charge la fonction de file d'attente à retard. Mais nous pouvons utiliser les deux caractéristiques de RabbitMQ pour courber la file d'attente de retard:

特性 1 、Durée de vie (TTL)

1.RabbitMQ peut définir x-expires pour la file d'attente

2. Définissez x-message-ttl pour Message

Grâce à ces deux façons de contrôler la durée de vie du message

  • S'il est défini par les propriétés de la file d'attente, tous les messages de la file d'attente ont le même délai d'expiration.
  • Si les messages sont définis individuellement, le TTL de chaque message peut être différent.
  • S'il expire (les deux sont définis en même temps, le premier délai d'expiration prévaudra), le message devient lettre morte (lettre morte)

特性 2 、Échanges de lettres mortes (DLX)

La file d'attente de RabbitMQ peut être configurée avec les deux paramètres x-dead-letter-exchange et x-dead-letter-routing-key (facultatif). Si une lettre morte apparaît dans la file d'attente, elle sera réacheminée et transférée vers le spécifié en fonction de ces deux paramètres. queue.

  • x-dead-letter-exchange: renvoyer la lettre morte à l'échange désigné après l'apparition de la lettre morte
  • x-dead-letter-routing-key: après l'apparition de la lettre morte, la lettre morte sera à nouveau envoyée selon la clé de routage spécifiée

La lettre morte dans la file d'attente comprend:

  • Le TTL du message ou de la file d'attente a expiré
  • La file d'attente atteint la longueur maximale
  • Le message a été rejeté par le consommateur (basic.reject ou basic.nack) et requeue = false

En combinant les deux fonctionnalités ci-dessus, après avoir défini la règle TTL, lorsqu'un message devient lettre morte dans une file d'attente, il peut être retransmis vers un autre échange ou clé de routage à l'aide de la fonctionnalité DLX, et le message peut être à nouveau consommé.

première méthode:

    /死信队列的应用//

    /**
     * DLX测试队列
     */
    @Bean
    public Queue DLXTestQueue() {
        Map<String, Object> args = new HashMap<>(2);
        args.put("x-dead-letter-exchange", "DL_exchange");
        args.put("x-dead-letter-routing-key", "DL_queue");
        return QueueBuilder.nonDurable("DLX-test-queue").withArguments(args).build();
    }

    @Bean
    public Exchange DLXTestExchange() {
        return ExchangeBuilder.directExchange("DLX-test-exchange").durable(true).build();
    }

    @Bean
    public Binding DLXTestBinding() {
        return new Binding("DLX-test-queue", Binding.DestinationType.QUEUE, "DLX-test-exchange", "DLX-test-queue", null);
    }


    ///声明一个死信队列,交换机,绑定//
    @Bean
    public Queue dlQueue() {
        return QueueBuilder.nonDurable("DL_queue").build();
    }

    @Bean
    public Exchange dlExchange() {
        return ExchangeBuilder.directExchange("DL_exchange").durable(true).build();
    }

    /**
     * 死信路由通过 DL_queue 绑定键绑定到死信队列上.
     */
    @Bean
    public Binding deadLetterBinding() {
        return new Binding("DL_queue", Binding.DestinationType.QUEUE, "DL_exchange", "DL_queue", null);
    }

envoyer:

    /**
     * 测试死信队列
     */
    @GetMapping("ttl")
    public Resp testTTL() {
        rabbitTemplate.convertAndSend("DLX-test-exchange", "DLX-test-queue", "去私信队列", messagePostProcessor -> {
            messagePostProcessor.getMessageProperties().setExpiration("10000");
            return messagePostProcessor;
        });
        return Resp.success("ok", null);
    }

 consommateur:

    @RabbitListener(queues = {"DL_queue"})
    public void DLXTestQueue(Message message, Channel channel) throws IOException {
        log.info("死信队列  10s 后 消费消息 {}", new String(message.getBody()));
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }

Méthode 2: Rabbitmq 3.5.7 et supérieur fournit un plug-in (rabbitmq-delay-message-exchange) pour réaliser la fonction de file d'attente retardée. Dans le même temps, le plugin dépend d'Erlang / OPT 18.0 et supérieur.

Adresse de téléchargement du plug-in: https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releases , veuillez vous référer à mon dernier article pour plus de détails .

Configuration:

package com.zoo.mq.config;

import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;


/**
 * @author: 谢飞
 */
@Configuration
public class RabbitMqConfig {

    /**
     * 定义延迟消息发送的队列.
     */
    @Bean
    public Queue delayQueue() {
        return QueueBuilder.nonDurable("delay_queue").build();
    }


    /交换机/

    /**
     * 定义一个用于延迟消息发送的交换机
     * 延时队列交换机 注意这里的交换机类型:CustomExchange
     */
    @Bean
    public CustomExchange delayExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange("delay_exchange", "x-delayed-message", true, false, args);
    }


    绑定/

    /**
     * 给延时队列绑定交换机
     */
    @Bean
    public Binding redirectBinding() {
        return BindingBuilder.bind(delayQueue()).to(delayExchange()).with("delay_key").noargs();
    }

}

Producteur:

    @GetMapping("sendTTL")
    public Resp sendTTL() {
        rabbitTemplate.convertAndSend("delay_exchange", "delay_key", "hello", messagePostProcessor -> {
            messagePostProcessor.getMessageProperties().setDelay(10000);
            return messagePostProcessor;
        });
        return Resp.success("ok", null);
    }

 consommateur:

    @RabbitListener(queues = {"delay_queue"})
    public void delayQueue(Message message, Channel channel) throws IOException {
        log.info("delay_queue  10s 后 消费消息 {}", new String(message.getBody()));
    }

Tester ok. 

Le nombre de messages envoyés à la file d'attente lors de l'utilisation du plug-in rabbitmq-delay-message-exchange peut ne pas être visible dans l'interface de gestion Web et n'affecte pas l'utilisation normale des fonctions

 

 

Je suppose que tu aimes

Origine blog.csdn.net/qq_36850813/article/details/103279801
conseillé
Classement