Начало работы с RabbitMQ? Давайте посмотрим на его коммутатор (обмен)

Java
Начало работы с RabbitMQ? Давайте посмотрим на его коммутатор (обмен)

Жизнь в конце концов станет одиночным путешествием, до одиночества — смятение, после одиночества — рост.

клин

Эта статья представляет собой очередь сообщенийRabbitMQтретья пуля.

Начало работы с RabbitMQиИнтеграция RabbitMQ+SpringBootВы можете щелкнуть эту ссылку, чтобы просмотреть ее. Сегодня я расскажу о том,RabbitMQвыключатель.

Эта статья для пониманияRabbitMQОчень важная статья заключается в том, что коммутатор является первой остановкой сообщения.Только поняв режим распределения коммутатора, мы можем узнать, по каким правилам разные коммутаторы распределяют сообщения, и можем ли мы понять, какой коммутатор следует использовать при столкновении с разными потребности бизнеса.


Желаю вам хорошего урожая, как сначала, так и потом смотреть, и иметь бесконечное счастье.

Код для этой статьи: Адрес облака кодаАдрес GitHub

1. 🔍Обмен

rabbit架构图

Во-первых, давайте поместим те, которые появляются почти в каждой статье, которую я рисовал в течение длительного времени.RabbitMQСхема архитектуры.

В первых двух статьях мы не использовали его явноExchange, используются по умолчаниюExchange,фактическиExchangeЭто очень важный компонент, и с ним существуют различные режимы распространения сообщений.

Позвольте мне кратко сказатьExchangeКакие виды бывают:

  1. fanout:Fanout-ExchangeОн будет отправлять полученные сообщения всем привязанным к нему очередям.

  2. direct:Direct-Exchangeбудет отправлять сообщения, которые он получает, иRoutingkeyТочно подобранная очередь (по умолчанию).

  3. topic:Topic-ExchangeАналогичен Direct-Exchange, но Topic-Exchange не нужно полностью сопоставлять, можно частично сопоставить.RoutingkeyЭто строка, разделенная точкой «.» (мы называем каждую независимую строку, разделенную точкой «.», словом).

  4. header:Header-ExchangeНе полагается на RoutingKey или отношение привязки для распространения сообщений, но сопоставляется на основе свойства заголовков в содержимом отправленного сообщения. Этот режим больше не используется и не будет обсуждаться в этой статье, пока все его знают.

В этой статье мы в основном сосредоточимся на первых трехExchangeЯ верю, что своими лаконичными словами и душевным мастерством живописи я дам вам хорошее объяснение, и стремлюсь к тому, чтобы старуха поняла.

Tip: код в этой статье демонстрирует прямое использование режима SpringBoot+RabbitMQ.

2. 📕Fanout-биржа

Первый взглядFanout-Exchange,Fanout-ExchangeЭтот переключатель, также известный как переключатель секторов, должен быть самым простым для понимания.

扇形交换机

ExchangeиQueueустановить обязательные отношения,Exchangeбудет распространяться на все привязки к немуQueue, десять границQueueСделайте десять копий сообщения для распространения.

Это отношение связывания определенно будет поддерживать таблицу эффективности, которая обычно равна O (1) с точки зрения эффективности алгоритма, поэтомуFanout-Exchangeсреди этих переключателейНайдите очередь, которую необходимо распределитьСамый быстрый переключатель.


Вот демонстрация кода:

    @Bean
    public Queue fanout1() {
        return new Queue("fanout1");
    }

    @Bean
    public Queue fanout2() {
        return new Queue("fanout2");
    }

    @Bean
    public FanoutExchange fanoutExchange() {
        // 三个构造参数:name durable autoDelete
        return new FanoutExchange("fanoutExchange", false, false);
    }

    @Bean
    public Binding binding1() {
        return BindingBuilder.bind(fanout1()).to(fanoutExchange());
    }

    @Bean
    public Binding binding2() {
        return BindingBuilder.bind(fanout2()).to(fanoutExchange());
    }

Для наглядности я создал две демонстрационные очереди, а затем создал однуFanoutExchange, и, наконец, установите отношение привязки для всех из них, чтобы завершить настройку привязки группы очередей и коммутаторов.

Затем напишите производителя и потребителя:

    public void sendFanout() {
        Client client = new Client();

        // 应读者要求,以后代码打印的地方都会改成log方式,这是一种良好的编程习惯,用System.out.println一般是不推荐的。
        log.info("Message content : " + client);

        rabbitTemplate.convertAndSend("fanoutExchange",null,client);
        System.out.println("消息发送完毕。");
    }

    @Test
    public void sendFanoutMessage() {
        rabbitProduce.sendFanout();
    }
@Slf4j
@Component("rabbitFanoutConsumer")
public class RabbitFanoutConsumer {
    @RabbitListener(queues = "fanout1")
    public void onMessage1(Message message, Channel channel) throws Exception {
        log.info("Message content : " + message);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        log.info("消息已确认");
    }

    @RabbitListener(queues = "fanout2")
    public void onMessage2(Message message, Channel channel) throws Exception {
        log.info("Message content : " + message);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        log.info("消息已确认");
    }

}

Эти два фрагмента кода очень просты для понимания, поэтому я не буду их повторять, если вы забудете, вы можете прочитать их.Первая бомба RabbitMQСодержание.

где код, который отправляет сообщение, имеет три параметра, первый параметрExchangeимя, второй параметрroutingKeyИмя этого параметра не используется в переключателе секторов, но будет использоваться в двух других типах переключателей.

Это конец подготовки кода, мы можем запустить метод send и запустить его~

После запуска проекта мы можем сначала посмотреть, вступает ли в силу связь между очередью и коммутатором, которую мы используем в консоли RabbitMQ.rabbitmqctl list_bindingsкоманда для просмотра отношения привязки.

扇形交换机绑定关系

Ключевую часть я отметил красным прямоугольником, что означает названиеfanoutExchangeОбмен привязан к двум очередям, одна называетсяfanout1, другой звонилfanout2.

Далее давайте посмотрим на консольную печать:

扇形交换机确认消息

Как видите, после отправки сообщения обе очереди получают сообщение, которое затем используется двумя нашими потребителями.

Подсказка:Если ваше демонстрационное приложение не имеет информации о потреблении после запуска, вы можете попробовать повторно запустить метод производителя для отправки сообщения.

3. 📗Прямой обмен

Direct-ExchangeЭто точно соответствующий переключатель. Мы использовали переключатель по умолчанию раньше. На самом деле переключатель по умолчанию является прямым типом.

Если прямые свитчи сравнивать с администраторами квартиры, то очереди — жильцы внутри. (обязательные отношения)

Администратору каждый день приходят всевозможные письма (сообщения), причем в адресах этих писем нужно не только указать адрес (ExchangeKey), но и указать, в какое домохозяйство отправить (routingKey), иначе сообщение не может быть доставлено.

扇形交换机

Возьмите приведенное выше изображение в качестве примера, подготовьте сообщение для отправки наSendServiceЭтот переключатель в основном используется для отправки услуг, поэтому он привязан к двум очередям, очереди SMS и очереди MAIL, для отправки коротких сообщений и электронных писем.

Наше сообщение в дополнение к указаниюExchangeKeyтакже необходимо указатьroutingKey,routingKeyВ соответствии с тем, какая очередь окончательно отправлена, в нашем примереroutingKeyЭто sms, где это сообщение будет передано в очередь SMS.


Прослушав предыдущий абзац, вы можете быть правы.routingKeyЯ еще не очень хорошо в этом разбираюсь, давайте попрактикуемся в предыдущем коде, и все должны его понять.

Готов к работе:

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

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

    @Bean
    public DirectExchange directExchange() {
        // 三个构造参数:name durable autoDelete
        return new DirectExchange("directExchange", false, false);
    }

    @Bean
    public Binding directBinding1() {
        return BindingBuilder.bind(directQueue1()).to(directExchange()).with("sms");
    }

    @Bean
    public Binding directBinding2() {
        return BindingBuilder.bind(directQueue2()).to(directExchange()).with("mail");
    }

Создайте две новые очереди, создайте новый прямой коммутатор и установите отношение привязки.

Пример кода здесь очень похож на приведенный выше код переключателя вентилятора, с той лишь разницей, что при привязке делается еще один вызов.withбудетroutingKeyнастраивать.

Таким образом, он устанавливается, когда обмен и очередь устанавливают отношения привязки.routingKey, после того как на коммутатор приходит сообщение, коммутатор выводитroutingKeyУстановите, когда он обнаружит, что устанавливает отношения привязки с очередьюroutingKey, а затем отправить сообщение в эту очередь.

Режиссер:

    public void sendDirect() {
        Client client = new Client();

        log.info("Message content : " + client);

        rabbitTemplate.convertAndSend("directExchange","sms",client);
        System.out.println("消息发送完毕。");
    }

потребитель:

@Slf4j
@Component("rabbitDirectConsumer")
public class RabbitDirectConsumer {
    @RabbitListener(queues = "directQueue1")
    public void onMessage1(Message message, Channel channel) throws Exception {
        log.info("Message content : " + message);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        log.info("消息已确认");
    }

    @RabbitListener(queues = "directQueue2")
    public void onMessage2(Message message, Channel channel) throws Exception {
        log.info("Message content : " + message);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        log.info("消息已确认");
    }

}

Схема эффекта выглядит следующим образом:

扇形交换机

Как мы и ожидали, только один потребитель сделал сообщение.

4. 📙Обмен темами

Topic-ExchangeВерсия прямого переключателя с нечетким соответствием, переключатель типа темы, поддерживает использование подстановочных знаков «*» и «#» для определения нечеткого ключа привязки, а затем следуетroutingKeyСоздайте нечеткую очередь соответствия для распределения.

  • *: Может нечетко соответствовать слову.

  • #: Возможность нечеткого сопоставления нуля или более слов.

Поскольку добавлены два определителя подстановочных знаков, переключатель темroutingKeyЕсть также некоторые изменения,routingKeyможно использовать.Отдельные слова.


Здесь мы непосредственно воспользуемся примером, чтобы проиллюстрировать это более наглядно:

Готов к работе:

    // 主题交换机示例
    @Bean
    public Queue topicQueue1() {
        return new Queue("topicQueue1");
    }

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

    @Bean
    public TopicExchange topicExchange() {
        // 三个构造参数:name durable autoDelete
        return new TopicExchange("topicExchange", false, false);
    }

    @Bean
    public Binding topicBinding1() {
        return BindingBuilder.bind(topicQueue1()).to(topicExchange()).with("sms.*");
    }

    @Bean
    public Binding topicBinding2() {
        return BindingBuilder.bind(topicQueue2()).to(topicExchange()).with("mail.#");
    }

Создайте две новые очереди, создайте новый переключатель темы и установите отношение привязки.

Пример кода здесь мы в основном смотрим на настройкиroutingKey,здесьroutingKeyИспользуются подстановочные знаки и используется середина.раздельно, значитtopicQueue1Потреблениеsmsвступительное сообщение,topicQueue2ПотреблениеmailСообщение в начале, подробности см. ниже.

Режиссер:

    public void sendTopic() {
        Client client = new Client();

        log.info("Message content : " + client);

        rabbitTemplate.convertAndSend("topicExchange","sms.liantong",client);
        System.out.println("消息发送完毕。");
    }

потребитель:

@Slf4j
@Component("rabbitTopicConsumer")
public class RabbitTopicConsumer {
    @RabbitListener(queues = "topicQueue1")
    public void onMessage1(Message message, Channel channel) throws Exception {
        log.info("Message content : " + message);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        log.info("消息已确认");
    }

    @RabbitListener(queues = "topicQueue2")
    public void onMessage2(Message message, Channel channel) throws Exception {
        log.info("Message content : " + message);
        channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        log.info("消息已确认");
    }

}

Вот сообщение, отправленное нашим продюсеромroutingKeyдаsms.liantong, он будет отправлен наtopicQueue1Очередь идти, вот сообщениеroutingKeyтакже нужно использовать.Изолированные и не могут быть правильно идентифицированы с другими символами.

если нашroutingKeyдаsms.123.liantong, то он не сможет найти соответствующую очередь, потому чтоtopicQueue1Подстановочные знаки, используемые для нечеткого сопоставления,*вместо#,Только#Может соответствовать нескольким словам.

Topic-ExchangeиDirect-ExchangeОчень похоже, повторять не буду, подстановочные знаки*и#Отличие тоже очень простое, можете попробовать сами.

постскриптум

Мне очень стыдно, что я не обновила свой текст в понедельник. Я пошла в больницу, чтобы сдать кровь, и я взяла три пробирки~ Сколько я могу съесть, чтобы компенсировать это~

RabbitMQ обновил три статьи. Содержание этих трех статей несколько базовое. В следующей статье будет обновлена ​​расширенная часть: в том числе предотвращение потери сообщений, предотвращение повторного использования сообщений и т. д., я надеюсь, что вы продолжите обращать внимание.


В последнее время я был под большим давлением. Youhu приказал мне перейти на уровень 3 до конца августа, поэтому лайки читателей очень важны для меня. Надеюсь, вы поднимете руку и поможете мне~

Ну вот и все содержание этого выпуска.Спасибо, что вы здесь.Приглашаем лайкать,собирать и комментировать эту статью.👍Каждый ваш лайк-самая большая мотивация для моего творчества.

Я Эр, псевдолитературный программист, который всегда хотел выводить знания, до встречи в следующем выпуске.

Код для этой статьи:Адрес облака кодаАдрес GitHub