Подробное объяснение основных концепций RabbitMQ

RabbitMQ

Во-первых, очередь сообщений

Промежуточное программное обеспечение очереди сообщений (MQ) относится к использованию эффективного и надежного механизма доставки сообщений для независимого от платформы обмена данными.Он может расширить обмен данными между процессами в распределенной среде и распространять данные на основе обмена данными.Системная интеграция. В основном он подходит для следующих сценариев:

  • Разделение проекта: Различные проекты или модули могут использовать промежуточное программное обеспечение сообщений для передачи данных, чтобы обеспечить относительную независимость модулей и добиться разделения.
  • Отсечение трафика: Пакетный трафик (например, данные seckill) может быть записан в промежуточное программное обеспечение сообщений, а затем обработан асинхронно несколькими потребителями.
  • Эластичное масштабирование: Возможности обработки и пропускная способность системы могут быть улучшены за счет горизонтального расширения промежуточного программного обеспечения сообщений.
  • опубликовать подписаться: Может использоваться в любой модели публикации-подписки.
  • Асинхронная обработка: Когда нам не нужно обрабатывать данные немедленно или нас не волнует результат обработки данных, мы можем использовать промежуточное ПО для асинхронной обработки.
  • резервное хранилище: ПО промежуточного слоя сообщений может постоянно хранить данные до тех пор, пока вы не закончите их использование, а затем удалите их.

2. Протокол AMQP

AMQP (Advanced Message Queuing Protocol) — это коммуникационный протокол прикладного уровня, который предоставляет унифицированные службы обмена сообщениями и предоставляет унифицированную спецификацию разработки промежуточного программного обеспечения сообщений. Разные клиенты могут отправлять сообщения промежуточному программному обеспечению или получать от него сообщения; клиенты, которые отправляют и получают сообщения, могут быть разработаны на разных языках и реализованы в разных технологиях, но должны следовать одному и тому же протоколу AMQP. Сам протокол AMQP включает в себя следующие три уровня:

  • Module Layer: Расположенный на самом высоком уровне протокола, он в основном определяет некоторые команды для вызова клиентом, и клиент может использовать эти команды для реализации своей собственной бизнес-логики. Например: вы можете использовать команду Queue.Declare, чтобы объявить очередь, или использовать Basic.Consume, чтобы подписаться на получение сообщений в очереди.
  • Session Layer: Расположенный на среднем уровне, он в основном отвечает за отправку команды клиента на сервер, а затем возвращает ответ сервера клиенту.Он в основном обеспечивает механизм синхронизации надежности и обработку ошибок для связи между клиентом и сервером.
  • Transport Layer: Расположенный на нижнем уровне, он в основном передает потоки двоичных данных, обеспечивая обработку кадров, мультиплексирование каналов, обнаружение ошибок и представление данных.

3. Введение в RabbitMQ

RabbitMQ полностью реализует протокол AMQP и основан на той же архитектуре модели. RabbitMQ реализуетAMQP 0-9-1На основе дополнительного расширения и может поддерживаться плагинамиAMQP 1.0. Так что в определенной степени RabbitMQ — это реализация AMQP на языке Erlang. RabbitMQ стал наиболее широко используемым промежуточным программным обеспечением для сообщений, основанным на многих превосходных функциях.Его основные функции заключаются в следующем:

  • Поддержка нескольких протоколов обмена сообщениями, в дополнение к AMQP, все версии протокола STOMP и протокола MQTT 3.1 могут поддерживаться через плагины;
  • Имеет множество типов переключателей, которые могут удовлетворить большинство потребностей использования;
  • Поддержка нескольких методов развертывания, простота развертывания;
  • Поддержка кросс-языковой разработки, такой как: Java, .NET, PHP, Python, JavaScript, Ruby, Go;
  • Высокая доступность и высокая пропускная способность могут быть достигнуты за счет кластеризации, а сервисные узлы разных версий в компьютерных залах и регионах также могут быть подключены через подключаемый модуль Federation;
  • Подключаемая аутентификация и авторизация, поддержка TLS и LDAP;
  • Поддержка непрерывной интеграции, возможность гибкого расширения с помощью различных плагинов;
  • Возможность мониторинга и управления с использованием нескольких средств, таких как HTTP API, инструменты командной строки и интерфейс пользовательского интерфейса.

4. Архитектура модели

RabbitMQ и AMQP следуют одной и той же архитектуре модели Пример архитектуры выглядит следующим образом:

1. Издатель

Издатели (или производители) несут ответственность за создание сообщений и их доставку на назначенные биржи.

2. Сообщение

Сообщение состоит из заголовка сообщения и тела сообщения. Заголовок сообщения используется для хранения метаданных, связанных с сообщением: таких как имя целевого обмена (exchange_name), ключ маршрутизации (RoundingKey) и другая дополнительная информация о конфигурации (свойства). Тело сообщения — это фактические данные, которые необходимо доставить.

3. Обмен

Биржа отвечает за получение сообщения от производителя и направляет сообщение в одну или несколько очередей.Если оно не может быть маршрутизировано, оно будет возвращено производителю или отброшено напрямую, в зависимости от обязательного свойства биржи:

  • Когда required имеет значение true: если обмен не может найти очередь, которая соответствует его собственному типу и ключу маршрутизации, он вернет сообщение производителю;
  • Когда обязательный имеет значение false: если биржа не может найти очередь, которая соответствует его собственному типу и ключу маршрутизации, он просто отбрасывает сообщение.

4. Ключ привязки

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

5. Ключ маршрутизации

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

6. Queue (очередь сообщений)

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

7. Потребитель

Потребители подписываются на интересующие очереди и несут ответственность за использование сообщений, хранящихся в очередях. Чтобы гарантировать, что сообщения могут надежно достигать потребителей из очереди, RabbitMQ предоставляет механизм подтверждения сообщения (подтверждение сообщения), который управляется параметром autoAck:

  • Когда autoAck имеет значение true: после того, как сообщение отправлено (записано в сокет TCP), потребление считается успешным, независимо от того, действительно ли потребитель использует эти сообщения. Когда TCP-соединение или канал неожиданно закрываются или потребитель неожиданно выходит из строя в процессе потребления, соответствующее сообщение теряется. Таким образом, этот режим может улучшить пропускную способность, но есть риск потери данных.
  • Когда autoAck имеет значение false: пользователь должен подтвердить вручную после завершения обработки данных. RabbitMQ считает, что сообщение было успешно обработано только после завершения ручного подтверждения пользователя. Это обеспечивает надежную доставку данных, но снижает пропускную способность системы.

8. Подключение

TCP-соединение, используемое для доставки сообщений.

9. Канал

RabbitMQ использует дизайн, аналогичный NIO (неблокирующий ввод-вывод), повторно использует TCP-соединения через каналы и обеспечивает изоляцию каждого канала, как при наличии независимого соединения Connection. Когда трафик данных не очень велик, использование технологии мультиплексирования соединений позволяет избежать значительных потерь производительности, вызванных созданием слишком большого количества соединений TCP.

10. Виртуальный хост

RabbitMQ реализует логическую группировку и изоляцию ресурсов через виртуальные хосты.Виртуальный хост — это небольшой сервер RabbitMQ с независимыми очередями, обменами и отношениями привязки. Пользователи могут создавать разные виртуальные хосты в соответствии с разными бизнес-сценариями.Виртуальные хосты полностью независимы.Вы не можете привязать коммутатор на vhost1 к очереди на vhost2, что может значительно обеспечить изоляцию между сервисами и безопасность данных. Имя виртуального хоста по умолчанию:/.

11. Broker

Реальное развертывание с запущенным сервисом RabbitMQ.

Пять, тип переключателя

RabbitMQ поддерживает множество типов обмена, обычно используются следующие четыре:

5.1 fanout

Это простейшая модель обмена, в которой сообщения направляются во все очереди, привязанные к обмену. Как показано на рисунке ниже, любое сообщение, отправленное на X-обмен, будет перенаправлено в две очереди Q1 и Q2.

5.2 direct

Направляйте сообщения в ту же очередь, что и BindingKey и RoundingKey. Как показано на рисунке ниже, когда RountingKey сообщения оранжевого цвета, сообщение будет перенаправлено в очередь Q1; когда RoundingKey сообщения черного или зеленого цвета, сообщение будет перенаправлено в очередь Q2.

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

5.3 topic

Направьте сообщение в очередь, BindingKey и RoundingKey которой совпадают. Правила сопоставления следующие:

  • RoundingKey и BindingKey состоят из нескольких слов с использованием запятых..подключить;
  • BindingKey поддерживает два специальных символа:#и*. в*для сопоставления слова,#Используется для соответствия нулю или более словам.

Ниже приведен пример в официальном документе.Ситуация привязки между обменом и очередью показана на рисунке.Ситуация маршрутизации на данный момент следующая:

  • Ключ маршрутизацииlazy.orange.elephantСообщение будет отправлено во все очереди;
  • Ключ маршрутизацииquick.orange.foxСообщение будет отправлено только в очередь Q1;
  • Ключ маршрутизацииlazy.brown.foxСообщение будет отправлено только в очередь Q2;
  • Ключ маршрутизацииlazy.pink.rabbitСообщение будет отправлено только в очередь Q2;
  • Ключ маршрутизацииquick.brown.foxСообщение не соответствует ни одной привязке;
  • Ключ маршрутизацииorangeилиquick.orange.male.rabbitСообщение также не соответствует ни одной привязке.

5.4 headers

Когда обмен привязан к очереди, набор пар ключ-значение может быть указан как BindingKey; набор атрибутов пары ключ-значение может быть указан в заголовках отправляемого сообщения, и когда эти атрибуты совпадают с BindingKey, сообщение будет направлено в эту очередь. Также можно использоватьx-matchПараметр указывает шаблон соответствия:

  • x-match = all: все пары "ключ-значение" считаются успешным совпадением;
  • x-match = any: если есть одна совпадающая пара ключ-значение, совпадение считается успешным.

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

6. Очередь недоставленных писем

Другой распространенной концепцией RabbitMQ является очередь недоставленных сообщений. Когда сообщение становится недоставленным письмом в очереди, его можно повторно отправить в обмен недоставленными письмами (Dead-Letter-Exchange на английском языке, DLX для краткости), любая очередь, привязанная к обмену недоставленными письмами. Они называются очередями недоставленных сообщений. Следует отметить, что обмены недоставленными сообщениями и очереди недоставленных сообщений точно такие же, как и обычные обмены и очереди, и создаются таким же образом, их имена выражают их функции, а не их типы. Обычное сообщение становится мертвой буквой по трем причинам:

  • Сообщение отклонено (Basic.Reject/Basic.Nack), а для параметра requeue установлено значение false;
  • срок действия сообщения истек;
  • Очередь достигла максимальной длины.

Мы можем установить параметр x-dead-letter-exchange в методе channel.queueDeclare, созданном очередью, чтобы добавить обмен недоставленными письмами в обычную очередь.Когда в очереди есть недоставленное письмо, недоставленное письмо будет отправлено в обмен недоставленными сообщениями. , а затем направить в очередь недоставленных сообщений. Пример выглядит следующим образом:

// 创建死信交换器
channel.exchangeDeclare("exchange.dlx", "direct");
// 声明死信队列
channel.queueDeclare(" queue.d1x ", true, false, false, null);
// 绑定死信交换器和死信队列
channel.queueBind("queue.dlx ", "exchange.dlx ", "routingkey");

Map<String, Object> args = new HashMap<>();
args.put("x-dead-letter-exchange", "exchange.dlx");
// 为名为 myqueue 的正常队列指定死信交换器
channel.queueDeclare("queue.normal", false, false, false, args);

Кроме того, вы также можете повторно указать ключ маршрутизации недоставленного письма.Если он не указан, по умолчанию будет использоваться исходный ключ маршрутизации.Метод сброса следующий:

args.put("x-dead-letter-routing-key", "some-routing-key");

использованная литература

  1. Чжу Чжунхуа, Практическое руководство RabbitMQ, Electronic Industry Press, 1 ноября 2017 г.
  2. Официальная документация:RabbitMQ Tutorials,Documentation: Table of Contents

Дополнительные статьи см. в [Full Stack Engineer Manual], адрес GitHub:GitHub.com/Black and WhiteShould/…