Жизнь в конце концов станет одиночным путешествием, до одиночества — смятение, после одиночества — рост.
клин
Эта статья представляет собой очередь сообщений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