Жизнь в конце концов станет одиночным путешествием, до одиночества — смятение, после одиночества — рост.
клин
Эта статья представляет собой очередь сообщенийRabbitMQтретья пуля.
Начало работы с RabbitMQиИнтеграция RabbitMQ+SpringBootВы можете щелкнуть эту ссылку, чтобы просмотреть ее. Сегодня я расскажу о том,RabbitMQвыключатель.
Эта статья для пониманияRabbitMQОчень важная статья заключается в том, что коммутатор является первой остановкой сообщения.Только поняв режим распределения коммутатора, мы можем узнать, по каким правилам разные коммутаторы распределяют сообщения, и можем ли мы понять, какой коммутатор следует использовать при столкновении с разными потребности бизнеса.
Желаю вам хорошего урожая, как сначала, так и потом смотреть, и иметь бесконечное счастье.
Код для этой статьи: Адрес облака кода Адрес GitHub
1. 🔍Обмен

Во-первых, давайте поместим те, которые появляются почти в каждой статье, которую я рисовал в течение длительного времени.RabbitMQСхема архитектуры.
В первых двух статьях мы не использовали его явноExchange, используются по умолчаниюExchange,фактическиExchangeЭто очень важный компонент, и с ним существуют различные режимы распространения сообщений.
Позвольте мне кратко сказатьExchangeКакие виды бывают:
-
fanout:
Fanout-ExchangeОн будет отправлять полученные сообщения всем привязанным к нему очередям. -
direct:
Direct-Exchangeбудет отправлять сообщения, которые он получает, иRoutingkeyТочно подобранная очередь (по умолчанию). -
topic:
Topic-ExchangeАналогичен Direct-Exchange, но Topic-Exchange не нужно полностью сопоставлять, можно частично сопоставить.RoutingkeyЭто строка, разделенная точкой «.» (мы называем каждую независимую строку, разделенную точкой «.», словом). -
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