Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

Résumé

Les articles sur le mode de message principal de RabbitMQ que j'ai lus auparavant sont tous basés sur JavaAPI. J'ai récemment lu le document officiel et j'ai découvert que ces modes de message de base peuvent tous être implémentés via Spring AMQP. J'ai donc résumé les compétences pratiques de RabbitMQ, y compris l'installation de RabbitMQ sous Windows et Linux, et l'implémentation de Spring AMQP avec 5 modes de message principaux. Je pense que cela sera utile aux amis qui veulent apprendre et réviser RabbitMQ.

introduction

RabbitMQ est l'un des middleware de messagerie open source les plus populaires, largement utilisé dans le monde entier. RabbitMQ est léger et facile à déployer, et peut prendre en charge plusieurs protocoles de messagerie. RabbitMQ peut être déployé dans un système distribué pour répondre aux exigences de haute disponibilité à grande échelle.

Concepts associés

Commençons par comprendre les concepts associés dans RabbitMQ. Ici, nous prenons le mode de routage dans les 5 modes de message comme exemple.

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Installation et configuration

Ensuite, nous introduisons l'installation et la configuration de RabbitMQ, et fournissons deux méthodes d'installation, Windows et Linux.

Installation sous Windows

  • Installez Erlang, adresse de téléchargement: http: //erlang.org/download/ot ...

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • Installez RabbitMQ, lien de téléchargement: https: //dl.bintray.com/rabbit ...

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • Une fois l'installation terminée, entrez le répertoire sbin sous le répertoire d'installation de RabbitMQ;

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • Entrez cmd dans la barre d'adresse et appuyez sur Entrée pour démarrer la ligne de commande, puis entrez la commande suivante pour démarrer la fonction de gestion.
rabbitmq-plugins enable rabbitmq_management

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Installation sous Linux

  • Téléchargez l'image Docker de rabbitmq 3.7.15;
docker pull rabbitmq:3.7.15
  • Utilisez la commande Docker pour démarrer le service;
docker run -p 5672:5672 -p 15672:15672 --name rabbitmq \
-d rabbitmq:3.7.15
  • Entrez dans le conteneur et ouvrez la fonction de gestion;
docker exec -it rabbitmq /bin/bash
rabbitmq-plugins enable rabbitmq_management

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • Activez le pare-feu pour faciliter l'accès au réseau externe.
firewall-cmd --zone=public --add-port=15672/tcp --permanent
firewall-cmd --zone=public --add-port=5672/tcp --permanent
firewall-cmd --reload

Accès et configuration

  • Consultez l'adresse de la page de gestion RabbitMQ pour vérifier si l'installation a réussi (utilisez l'adresse IP du serveur pour accéder sous Linux): http: // localhost: 15672 /

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • Entrez le mot de passe du compte et connectez-vous, utilisez ici le mot de passe du compte par défaut pour vous connecter: invité invité
  • Créez un compte et définissez son rôle d'administrateur: mall mall

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • Créez un nouvel hôte virtuel comme: / mall

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • Cliquez sur l'utilisateur du centre commercial pour accéder à la page de configuration de l'utilisateur;

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • Configurer les autorisations de l'hôte virtuel pour les utilisateurs du centre commercial;

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

  • À ce stade, la configuration de RabbitMQ est terminée.

5 modes de message

Ces 5 modes de message sont à la base de la construction d'une application de messagerie basée sur RabbitMQ, et nous devons les comprendre fermement. Les amis qui ont étudié RabbitMQ auraient dû connaître l'implémentation Java de ces modes de message. Ici, nous utilisons Spring AMQP pour les implémenter.

Mode simple

Le mode simple est le mode de message le plus simple, il contient un producteur, un consommateur et une file d'attente. Le producteur envoie un message à la file d'attente, et le consommateur obtient le message de la file d'attente et le consomme.

Diagramme de mode

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Implémentation Spring AMQP

  • Tout d'abord, vous devez ajouter des dépendances Spring AMQP dans pom.xml;
<!--Spring AMQP依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
  • Puis modifiez application.yml et ajoutez la configuration appropriée de RabbitMQ;
spring:
  rabbitmq:
    host: localhost
    port: 5672
    virtual-host: /mall
    username: mall
    password: mall
    publisher-confirms: true #消息发送到交换器确认
    publisher-returns: true #消息发送到队列确认
  • Ajoutez une configuration Java liée au mode simple, créez une file d'attente nommée simple.hello, un producteur et un consommateur;
/**
 * Created by macro on 2020/5/19.
 */
@Configuration
public class SimpleRabbitConfig {

    @Bean
    public Queue hello() {
        return new Queue("simple.hello");
    }

    @Bean
    public SimpleSender simpleSender(){
        return new SimpleSender();
    }

    @Bean
    public SimpleReceiver simpleReceiver(){
        return new SimpleReceiver();
    }

}
  • Le producteur envoie un message à la file d'attente simple.hello via la méthode send;
/**
 * Created by macro on 2020/5/19.
 */
public class SimpleSender {

    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleSender.class);

    @Autowired
    private RabbitTemplate template;

    private static final String queueName="simple.hello";

    public void send() {
        String message = "Hello World!";
        this.template.convertAndSend(queueName, message);
        LOGGER.info(" [x] Sent '{}'", message);
    }

}
  • Les consommateurs reçoivent les messages de la file d'attente simple.hello;
/**
 * Created by macro on 2020/5/19.
 */
@RabbitListener(queues = "simple.hello")
public class SimpleReceiver {

    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleReceiver.class);

    @RabbitHandler
    public void receive(String in) {
        LOGGER.info(" [x] Received '{}'", in);
    }

}
  • Ajoutez une interface de test au contrôleur et appelez cette interface pour commencer à envoyer des messages;
/**
 * Created by macro on 2020/5/19.
 */
@Api(tags = "RabbitController", description = "RabbitMQ功能测试")
@Controller
@RequestMapping("/rabbit")
public class RabbitController {

    @Autowired
    private SimpleSender simpleSender;

    @ApiOperation("简单模式")
    @RequestMapping(value = "/simple", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult simpleTest() {
        for(int i=0;i<10;i++){
            simpleSender.send();
            ThreadUtil.sleep(1000);
        }
        return CommonResult.success(null);
    }
}
  • Les résultats après l'exécution sont les suivants, vous pouvez constater que le producteur envoie un message à la file d'attente et que le consommateur obtient le message de la file d'attente et le consomme.

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Mode de fonctionnement

Le mode de travail est un mode dans lequel les messages sont envoyés à plusieurs consommateurs concurrents. Il comprend un producteur, deux consommateurs et une file d'attente. Deux consommateurs sont liés à une file d'attente en même temps. Lorsque les consommateurs reçoivent des messages pour traiter des tâches chronophages, les consommateurs inactifs reçoivent et consomment les messages de la file d'attente.

Diagramme de mode

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Implémentation Spring AMQP

  • Ajoutez une configuration Java liée au mode de travail, créez une file d'attente nommée work.hello, un producteur et deux consommateurs;
/**
 * Created by macro on 2020/5/19.
 */
@Configuration
public class WorkRabbitConfig {

    @Bean
    public Queue workQueue() {
        return new Queue("work.hello");
    }

    @Bean
    public WorkReceiver workReceiver1() {
        return new WorkReceiver(1);
    }

    @Bean
    public WorkReceiver workReceiver2() {
        return new WorkReceiver(2);
    }

    @Bean
    public WorkSender workSender() {
        return new WorkSender();
    }

}
  • Le producteur envoie un message à la file d'attente work.hello via la méthode send, le message contient un certain nombre de nombres;
/**
 * Created by macro on 2020/5/19.
 */
public class WorkSender {

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkSender.class);

    @Autowired
    private RabbitTemplate template;

    private static final String queueName = "work.hello";

    public void send(int index) {
        StringBuilder builder = new StringBuilder("Hello");
        int limitIndex = index % 3+1;
        for (int i = 0; i < limitIndex; i++) {
            builder.append('.');
        }
        builder.append(index+1);
        String message = builder.toString();
        template.convertAndSend(queueName, message);
        LOGGER.info(" [x] Sent '{}'", message);
    }

}
  • Deux consommateurs reçoivent des messages de la file d'attente work.hello, nommés respectivement instance 1 et instance 2. Plus il y a de nombres dans le message, plus cela prend du temps;
/**
 * Created by macro on 2020/5/19.
 */
@RabbitListener(queues = "work.hello")
public class WorkReceiver {

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkReceiver.class);

    private final int instance;

    public WorkReceiver(int i) {
        this.instance = i;
    }

    @RabbitHandler
    public void receive(String in) {
        StopWatch watch = new StopWatch();
        watch.start();
        LOGGER.info("instance {} [x] Received '{}'", this.instance, in);
        doWork(in);
        watch.stop();
        LOGGER.info("instance {} [x] Done in {}s", this.instance, watch.getTotalTimeSeconds());
    }

    private void doWork(String in) {
        for (char ch : in.toCharArray()) {
            if (ch == '.') {
                ThreadUtil.sleep(1000);
            }
        }
    }

}
  • Ajoutez une interface de test au contrôleur et appelez cette interface pour commencer à envoyer des messages;
/**
 * Created by macro on 2020/5/19.
 */
@Api(tags = "RabbitController", description = "RabbitMQ功能测试")
@Controller
@RequestMapping("/rabbit")
public class RabbitController {
    
    @Autowired
    private WorkSender workSender;

    @ApiOperation("工作模式")
    @RequestMapping(value = "/work", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult workTest() {
        for(int i=0;i<10;i++){
            workSender.send(i);
            ThreadUtil.sleep(1000);
        }
        return CommonResult.success(null);
    }
}
  • Les résultats après l'opération sont les suivants. On constate que le producteur envoie des messages contenant des nombres différents à la file d'attente. Les consommateurs d'instance 1 et d'instance 2 se font concurrence et consomment respectivement une partie des messages.

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Modèle de publication / abonnement

Le modèle de publication / abonnement fait référence à un modèle dans lequel les messages sont envoyés à plusieurs consommateurs en même temps (similaire à un formulaire de diffusion). Il comprend un producteur, deux consommateurs, deux files d'attente et un commutateur. Deux consommateurs sont liés à des files d'attente différentes en même temps et les deux files d'attente sont liées à l'échange. Le producteur envoie un message à l'échange, et tous les consommateurs reçoivent et consomment le message.

Diagramme de mode

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Implémentation Spring AMQP

  • Ajoutez la configuration Java liée au mode de publication / abonnement, créez un échange nommé exchange.fanout, un producteur, deux consommateurs et deux files d'attente anonymes, et liez les deux files d'attente anonymes à l'échange;
/**
 * Created by macro on 2020/5/19.
 */
@Configuration
public class FanoutRabbitConfig {

    @Bean
    public FanoutExchange fanout() {
        return new FanoutExchange("exchange.fanout");
    }

    @Bean
    public Queue fanoutQueue1() {
        return new AnonymousQueue();
    }

    @Bean
    public Queue fanoutQueue2() {
        return new AnonymousQueue();
    }

    @Bean
    public Binding fanoutBinding1(FanoutExchange fanout, Queue fanoutQueue1) {
        return BindingBuilder.bind(fanoutQueue1).to(fanout);
    }

    @Bean
    public Binding fanoutBinding2(FanoutExchange fanout, Queue fanoutQueue2) {
        return BindingBuilder.bind(fanoutQueue2).to(fanout);
    }

    @Bean
    public FanoutReceiver fanoutReceiver() {
        return new FanoutReceiver();
    }

    @Bean
    public FanoutSender fanoutSender() {
        return new FanoutSender();
    }

}
  • Le producteur envoie un message à l'échange exchange.fanout via la méthode d'envoi, et le message contient un certain nombre de nombres;
/**
 * Created by macro on 2020/5/19.
 */
public class FanoutSender {
    private static final Logger LOGGER = LoggerFactory.getLogger(FanoutSender.class);
    @Autowired
    private RabbitTemplate template;

    private static final String exchangeName = "exchange.fanout";

    public void send(int index) {
        StringBuilder builder = new StringBuilder("Hello");
        int limitIndex = index % 3 + 1;
        for (int i = 0; i < limitIndex; i++) {
            builder.append('.');
        }
        builder.append(index + 1);
        String message = builder.toString();
        template.convertAndSend(exchangeName, "", message);
        LOGGER.info(" [x] Sent '{}'", message);
    }

}
  • Les consommateurs reçoivent les messages de la file d'attente anonyme liée. Plus il y a de numéros dans le message, plus il prendra de temps. Étant donné que le consommateur peut obtenir et consommer des messages à partir de deux files d'attente, ils peuvent être considérés comme deux consommateurs avec des noms différents. Sont l'instance 1 et l'instance 2;
/**
 * Created by macro on 2020/5/19.
 */
public class FanoutReceiver {

    private static final Logger LOGGER = LoggerFactory.getLogger(FanoutReceiver.class);

    @RabbitListener(queues = "#{fanoutQueue1.name}")
    public void receive1(String in) {
        receive(in, 1);
    }

    @RabbitListener(queues = "#{fanoutQueue2.name}")
    public void receive2(String in) {
        receive(in, 2);
    }

    private void receive(String in, int receiver) {
        StopWatch watch = new StopWatch();
        watch.start();
        LOGGER.info("instance {} [x] Received '{}'", receiver, in);
        doWork(in);
        watch.stop();
        LOGGER.info("instance {} [x] Done in {}s", receiver, watch.getTotalTimeSeconds());
    }

    private void doWork(String in) {
        for (char ch : in.toCharArray()) {
            if (ch == '.') {
                ThreadUtil.sleep(1000);
            }
        }
    }

}
  • Ajoutez une interface de test au contrôleur et appelez cette interface pour commencer à envoyer des messages;
/**
 * Created by macro on 2020/5/19.
 */
@Api(tags = "RabbitController", description = "RabbitMQ功能测试")
@Controller
@RequestMapping("/rabbit")
public class RabbitController {
    
    @Autowired
    private FanoutSender fanoutSender;

    @ApiOperation("发布/订阅模式")
    @RequestMapping(value = "/fanout", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult fanoutTest() {
        for(int i=0;i<10;i++){
            fanoutSender.send(i);
            ThreadUtil.sleep(1000);
        }
        return CommonResult.success(null);
    }
}
  • Les résultats de l'opération sont les suivants: on constate que le producteur envoie des messages contenant différents nombres de nombres à la file d'attente, et l'instance 1 et l'instance 2 obtiennent et consomment simultanément des messages.

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Mode de routage

Le mode de routage est un mode qui peut envoyer des messages de manière sélective à plusieurs consommateurs en fonction de la clé de routage. Il comprend un producteur, deux consommateurs, deux files d'attente et un commutateur. Deux consommateurs sont liés à différentes files d'attente en même temps, les deux files d'attente sont liées au commutateur via la clé de routage, le producteur envoie un message au commutateur, le commutateur transfère vers différentes files d'attente via la clé de routage et le consommateur lié à la file d'attente reçoit et consomme nouvelles.

Diagramme de mode

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Implémentation Spring AMQP

  • Ajoutez une configuration Java liée au mode de routage, créez un commutateur nommé exchange.direct, un producteur, deux consommateurs et deux files d'attente anonymes, les files d'attente sont liées au commutateur via la clé de routage et les clés de routage de la file d'attente 1 sont orange et noires , Les clés de routage de la file d'attente 2 sont vertes et noires;
/**
 * Created by macro on 2020/5/19.
 */
@Configuration
public class DirectRabbitConfig {

    @Bean
    public DirectExchange direct() {
        return new DirectExchange("exchange.direct");
    }

    @Bean
    public Queue directQueue1() {
        return new AnonymousQueue();
    }

    @Bean
    public Queue directQueue2() {
        return new AnonymousQueue();
    }

    @Bean
    public Binding directBinding1a(DirectExchange direct, Queue directQueue1) {
        return BindingBuilder.bind(directQueue1).to(direct).with("orange");
    }

    @Bean
    public Binding directBinding1b(DirectExchange direct, Queue directQueue1) {
        return BindingBuilder.bind(directQueue1).to(direct).with("black");
    }

    @Bean
    public Binding directBinding2a(DirectExchange direct, Queue directQueue2) {
        return BindingBuilder.bind(directQueue2).to(direct).with("green");
    }

    @Bean
    public Binding directBinding2b(DirectExchange direct, Queue directQueue2) {
        return BindingBuilder.bind(directQueue2).to(direct).with("black");
    }

    @Bean
    public DirectReceiver receiver() {
        return new DirectReceiver();
    }


    @Bean
    public DirectSender directSender() {
        return new DirectSender();
    }

}
  • Le producteur envoie un message à l'échange exchange.direct via la méthode d'envoi, en utilisant différentes clés de routage lors de l'envoi, et sera redirigé vers différentes files d'attente en fonction de la clé de routage;
/**
 * Created by macro on 2020/5/19.
 */
public class DirectSender {

    @Autowired
    private RabbitTemplate template;

    private static final String exchangeName = "exchange.direct";

    private final String[] keys = {"orange", "black", "green"};

    private static final Logger LOGGER = LoggerFactory.getLogger(DirectSender.class);

    public void send(int index) {
        StringBuilder builder = new StringBuilder("Hello to ");
        int limitIndex = index % 3;
        String key = keys[limitIndex];
        builder.append(key).append(' ');
        builder.append(index+1);
        String message = builder.toString();
        template.convertAndSend(exchangeName, key, message);
        LOGGER.info(" [x] Sent '{}'", message);
    }

}
  • Les consommateurs reçoivent les messages de la file d'attente anonyme qui leur est liée. Étant donné que le consommateur peut obtenir et consommer des messages à partir de deux files d'attente, il peut être considéré comme deux consommateurs, nommés respectivement instance 1 et instance 2;
/**
 * Created by macro on 2020/5/19.
 */
public class DirectReceiver {
    private static final Logger LOGGER = LoggerFactory.getLogger(DirectReceiver.class);

    @RabbitListener(queues = "#{directQueue1.name}")
    public void receive1(String in){
        receive(in, 1);
    }

    @RabbitListener(queues = "#{directQueue2.name}")
    public void receive2(String in){
        receive(in, 2);
    }

    private void receive(String in, int receiver){
        StopWatch watch = new StopWatch();
        watch.start();
        LOGGER.info("instance {} [x] Received '{}'", receiver, in);
        doWork(in);
        watch.stop();
        LOGGER.info("instance {} [x] Done in {}s", receiver, watch.getTotalTimeSeconds());
    }

    private void doWork(String in){
        for (char ch : in.toCharArray()) {
            if (ch == '.') {
                ThreadUtil.sleep(1000);
            }
        }
    }

}
  • Ajoutez une interface de test au contrôleur et appelez cette interface pour commencer à envoyer des messages;
/**
 * Created by macro on 2020/5/19.
 */
@Api(tags = "RabbitController", description = "RabbitMQ功能测试")
@Controller
@RequestMapping("/rabbit")
public class RabbitController {

    @Autowired
    private DirectSender directSender;

    @ApiOperation("路由模式")
    @RequestMapping(value = "/direct", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult directTest() {
        for(int i=0;i<10;i++){
            directSender.send(i);
            ThreadUtil.sleep(1000);
        }
        return CommonResult.success(null);
    }
}
  • Les résultats après l'exécution sont les suivants. On peut constater que le producteur envoie des messages contenant différentes clés de routage à la file d'attente. L'instance 1 reçoit des messages orange et noir et l'instance 2 reçoit des messages verts et noirs.

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Motif générique

Le modèle générique est un modèle qui peut envoyer des messages de manière sélective à plusieurs consommateurs en fonction des règles de correspondance des clés de routage. Il comprend un producteur, deux consommateurs, deux files d'attente et un commutateur. Deux consommateurs sont liés à différentes files d'attente en même temps, les deux files d'attente sont liées au commutateur via des règles de correspondance de clé de routage, le producteur envoie des messages au commutateur et le commutateur transfère vers différentes files d'attente via les règles de correspondance des clés de routage et la consommation liée à la file d'attente La personne reçoit et consomme le message.

Symbole correspondant spécial

  • *: Un seul mot peut être mis en correspondance;
  • #: Vous pouvez faire correspondre zéro ou plusieurs mots.

Diagramme de mode

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Implémentation Spring AMQP

  • Ajoutez une configuration Java associée à un modèle générique, créez un échange nommé exchange.topic, un producteur, deux consommateurs et deux files d'attente anonymes, faites correspondre * .orange. * Et *. *. Lapin à la file d'attente 1, faites correspondre lazy . # Envoyer à la file d'attente 2;
/**
 * Created by macro on 2020/5/19.
 */
@Configuration
public class TopicRabbitConfig {

    @Bean
    public TopicExchange topic() {
        return new TopicExchange("exchange.topic");
    }

    @Bean
    public Queue topicQueue1() {
        return new AnonymousQueue();
    }

    @Bean
    public Queue topicQueue2() {
        return new AnonymousQueue();
    }

    @Bean
    public Binding topicBinding1a(TopicExchange topic, Queue topicQueue1) {
        return BindingBuilder.bind(topicQueue1).to(topic).with("*.orange.*");
    }

    @Bean
    public Binding topicBinding1b(TopicExchange topic, Queue topicQueue1) {
        return BindingBuilder.bind(topicQueue1).to(topic).with("*.*.rabbit");
    }

    @Bean
    public Binding topicBinding2a(TopicExchange topic, Queue topicQueue2) {
        return BindingBuilder.bind(topicQueue2).to(topic).with("lazy.#");
    }

    @Bean
    public TopicReceiver topicReceiver() {
        return new TopicReceiver();
    }

    @Bean
    public TopicSender topicSender() {
        return new TopicSender();
    }

}
  • Le producteur envoie un message à l'échange exchange.topic via la méthode d'envoi, et le message contient différentes clés de routage;
/**
 * Created by macro on 2020/5/19.
 */
public class TopicSender {

    @Autowired
    private RabbitTemplate template;

    private static final String exchangeName = "exchange.topic";

    private static final Logger LOGGER = LoggerFactory.getLogger(TopicSender.class);


    private final String[] keys = {"quick.orange.rabbit", "lazy.orange.elephant", "quick.orange.fox",
            "lazy.brown.fox", "lazy.pink.rabbit", "quick.brown.fox"};

    public void send(int index) {
        StringBuilder builder = new StringBuilder("Hello to ");
        int limitIndex = index%keys.length;
        String key = keys[limitIndex];
        builder.append(key).append(' ');
        builder.append(index+1);
        String message = builder.toString();
        template.convertAndSend(exchangeName, key, message);
        LOGGER.info(" [x] Sent '{}'",message);
        System.out.println(" [x] Sent '" + message + "'");
    }

}
  • Les consommateurs reçoivent les messages de la file d'attente anonyme qui leur est liée. Étant donné que le consommateur peut obtenir et consommer des messages à partir de deux files d'attente, il peut être considéré comme deux consommateurs, nommés respectivement instance 1 et instance 2;
/**
 * Created by macro on 2020/5/19.
 */
public class TopicReceiver {

    private static final Logger LOGGER = LoggerFactory.getLogger(TopicReceiver.class);

    @RabbitListener(queues = "#{topicQueue1.name}")
    public void receive1(String in){
        receive(in, 1);
    }

    @RabbitListener(queues = "#{topicQueue2.name}")
    public void receive2(String in){
        receive(in, 2);
    }

    public void receive(String in, int receiver){
        StopWatch watch = new StopWatch();
        watch.start();
        LOGGER.info("instance {} [x] Received '{}'", receiver, in);
        doWork(in);
        watch.stop();
        LOGGER.info("instance {} [x] Done in {}s", receiver, watch.getTotalTimeSeconds());
    }

    private void doWork(String in){
        for (char ch : in.toCharArray()) {
            if (ch == '.') {
                ThreadUtil.sleep(1000);
            }
        }
    }

}
  • Ajoutez une interface de test au contrôleur et appelez cette interface pour commencer à envoyer des messages;
/**
 * Created by macro on 2020/5/19.
 */
@Api(tags = "RabbitController", description = "RabbitMQ功能测试")
@Controller
@RequestMapping("/rabbit")
public class RabbitController {

    @Autowired
    private TopicSender topicSender;

    @ApiOperation("通配符模式")
    @RequestMapping(value = "/topic", method = RequestMethod.GET)
    @ResponseBody
    public CommonResult topicTest() {
        for(int i=0;i<10;i++){
            topicSender.send(i);
            ThreadUtil.sleep(1000);
        }
        return CommonResult.success(null);
    }
}
  • Les résultats de l'opération sont les suivants: on constate que le producteur envoie des messages contenant différentes clés de routage à la file d'attente, et l'instance 1 et l'instance 2 obtiennent respectivement des messages correspondants.

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Je ne comprends même pas les 5 principaux modes de message de RabbitMQ et j'ose dire que j'utiliserai des files d'attente de messages.

 

Référence

Tutoriels RabbitMQ: https: //www.rabbitmq.com/gets ...

Adresse source du projet

https: //github.com/macrozheng ...

Je suppose que tu aimes

Origine blog.csdn.net/yunduo1/article/details/109116006
conseillé
Classement