Перейти к содержанию

RabbitMQ

Преимущества

Преимуществом RabbitMQ является возможность настраивать гибкие и сложные сценарии маршрутизации сообщений.

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

Note

Подробнее с документацией RabbitMQ вы можете ознакомиться на официальном сайте

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

Необходимость следить за текущим статусом всех сообщений сказывается на прозводительности RabbitMQ. При действительно больших объемах сообщений, RabbitMQ начинает деградировать. Однако, если это был "разовый наплыв", то по мере того, как потребители будут освобождать очередь, "самочувствие" RabbitMQ будет воостанавливаться.

Если ваш сценарий не подразумевает обработки десятков миллионов сообщений постоянным потоком, а также требует построения сложных сценариев обработки - RabbitMQ будет для вас отличным выбором.

Основные концепции

Если вы хотите досконально разобраться в том, как работает RabbitMQ, вам стоит посетить их оффициальный сайт. Здесь же вы найдете верхнеуровневый разбор основных понятий и примеры использования.

Сущности

RabbitMQ работает с тремя основными сущностями:

  • Exchange - ("обменник") точка приема сообщений от publisher'ов
  • Queue - (очередь) точка выдачи сообщения consumer'ам
  • Binding - (связь) отношение между queue-exchange или exchange-exchange

Правила маршрутизации

Правила доставки сообщений до потребителей зависят от типа exchange и параметров binding. Все основные варианты будут рассмотрены в примерах.

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

  1. Publisher отправляет сообщение в exchange, указывая его routing_key и заголовки, в соответствии с которыми будет происходить маршрутизация
  2. exchange в зависимости от параметров сообщения определяет, в какие из подписанных на него bindings нужно отправить сообщение
  3. binding доставляют сообщение до queue или другого exchange (в таком случае он отправит его дальше в соответсвии со своими правилами)
  4. queue, получив сообщение, отправляет его одному (свободному на данный момент) из подписанных потребителей (PUSH API)

Tip

По умолчанию все очереди имеют binding к default exchange (тип Direct) с routing key, соответсвующим их имени. В Propan именно в этот exchange подключаются очереди и отправляются сообщения по умолчанию, если не указан другой exchange явным образом.

При подключении очереди к любому другому exchange, она все также остается подписанной на default exchange. Будьте аккуратны с этим.

На этом этапе сообщение попадает в ваше приложение - и вы приступаете к его обработке.

Статусы сообщений

RabbitMQ требует подтверждения обработки сообщений: только после этого он сможет удалить его из очереди.

Такое подтверждение может быть как позитивным (Acknowledgement - ack), если сообщение было успешно обработано, так и негативным (Negative Acknowledgement - nack), если сообщение было обработано с ошибкой.

При этом, в случае ошибки, сообщение может быть также извлечено из очереди (reject), иначе, после негативного подтверждения оно уйдет на обработку в очередь снова.

В большинстве случаев Propan сам совершает все необходимые действия: однако, если вы хотите управлять жизенным циклом сообщений напрямую, вы можете получить доступ к самому объекту сообщения и вызывать соотвествующие методы напрямую. Это может быть полезно, если вы хотите реализовать политику "at most once" и вам нужно подтвердить получение сообщения до его фактической обработки.

Особенности Propan

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

Propan предлагает вам придерживаться схемы отношения exchange:queue как 1:N, что позволит значительно упростить схему взаимодействия между вашими сервисами. Лучше создать дополнительную очередь под новый exchange, чем подписать на него уже существующую.

Однако, если вы хотите снизить количество сущностей в вашем RabbitMQ, и тем самым оптимизировать его производительность (или вы точно знаете что делаете), Propan оставляет вам возможность создавать bindings напрямую. В остальных случаях, параметры подключения являются неотъемлемой частью сущностей RabbitQueue и RabbitExchange в Propan.