16. Брокеры сообщений и очереди
09.09.2023
Скачать
К списку выпусков
Почему и как я использовал брокеры сообщений в своих проектах?
Я использовал RabbitMQ для доставки E-mail и slack-нотификаций.
С опытом пришло понимание, что в старых системах я также мог не использовать брокер сообщений.
Например, доставка почты могла выполняться обычным batch processing'ом.
Я использовал по большей части очереди из-за ограничений PHP, в котором нетривиально
запустить ту же отправку письма асинхронно, но даже это на самом деле не нужно было в
моем случае, т.к. отправка письма происходила через postfix, установленный на том же сервере.
У postfix'а уже есть встроенная очередь сообщений на доставку.
Брокеры сообщений и очереди - разные решения.
Брокер сообщений часто представляет собой надстройку над очередями или их разновидностями.
Что такое очередь?
Очередь (англ. queue) — это структура данных, добавление и удаление элементов в которой происходит
путём операций и соответственно. Притом первым из очереди удаляется элемент, который был помещен
туда первым, то есть в очереди реализуется принцип «первым вошел — первым вышел»
(англ. first-in, first-out — FIFO).
Говоря о разработке ПО, сама по себе очередь - это уже усложнение.
Если предполагается гарантировать клиенту очередность доставки, то это уже усложнение.
Желательно настаивать на возможности задвоения событий и отсутсвии гарантий об очередности доставки.
Что такое брокер сообщений?
Брокер сообщений — это программное обеспечение или служба, которая обеспечивает
обмен сообщениями между различными системами, приложениями или компонентами.
Он используется для облегчения асинхронного обмена сообщениями и может поддерживать
различные модели обмена сообщениями, такие как очереди, топики, паблиш-сабскрайб (pub/sub) и другие.
Типы гарантий доставки сообщений:
-
at most once: простая (как UDP или как события в среде, где более
важно актуальное событие, например видео игры);
-
at least once: сложнее, но все еще просто (можно до определенной
степени сравнить с TCP пакетом, где в силу проблем в сети, ПО и т.д.
могут случиться задвоения пакетов, хотя и есть механизм дедупликации);
-
exactly once: самый сложный особенно, если доставка
сообщений очереди происходит через сетевую среду.
RabbitMQ
Messaging enables software applications to connect and scale. Applications can
connect to
each other, as components of a larger application, or to user devices and data. Messaging
is asynchronous, decoupling applications by separating sending and receiving data.
Connect. Использование брокера сообщений в качестве транспорта.
Scale. Легко можно масштабировать и реализовать механизм, например, fan-out, когда одно
сообщение черед настроенный обменник (exchange) попадает сразу в несколько очередей. Оменники можно также
комбинировать достигая дополнительного уровня масштабирования.
Когда использовать брокеры сообщений?
Если я скажу, что такие примеры есть, то это будет очень сильным утверждением. Часто, бывает несколько возможных
решений.
Потенциальные причины в пользу брокера сообщений:
- нужна моментальная отправка сообщений и старый добрый batch processing не решает задачи;
- повышения доступности: отдельные брокеры выполняют простейшую функцию и поэтому могут показать себя более
стабильными, чем потребители сообщений;
- потребность легкого масштабирования через увеличение количества реплик потребителей сообщений, настройки
сложных маршрутов доставки сообщений;
- общение между решениями, реализованными на разных технологиях.
Каждый из этих пунктов в отдельности не является гарантией почему нужно использовать брокеры сообщений. Желательно
принимать решение по совокупности указанных выше причин.
Проблемы связанные с брокерами сообщений
- расширение стека:
-
мониторинг, алертинг не только основной системы, но и брокера сообщений);
-
мониторинг работы косьюмеров;
-
повышается сложность функционального тестирования (готовую систему с брокером сообщений
захочется проверить всю и для этого развернуть максимально близкий к production-среде стек).
-
отсутсвие атомарности отправки сообщения
(можно использовать паттерн
Transactional Outbox);
-
дополнительная сложность управления сообщениями в очереди:
- повторная передача сообщения в очередь;
- повторная доставка сообщений;
-
обеспечение очередности, - если действительно стоит такая задача - в конкурентной среде
(если, предположим, HTTP запросы к сервису пришли последовательно, то из-за конкурентного
выполнения кода прозведенные ими сообщения, в очередь могут быть записаны в обратном порядке);
-
где хранить недоставленные сообщения, где хранить причину недоставки
(или отказа обработки) сообщения, т.е. нужно персистентное хранилище.
Выводы
-
используем batch processing до тех пор, пока это возможно, избегаем предварительной оптимизации
(возможно клиенту не так важно получать сообщения максимально оперативно);
-
синхронные решения проще в реализации асинхронных;
если есть брокер сообщений, то может его стоит заменить на синхронные вызовы и отказаться от брокера?
-
используем простые маханизмы на базе транзакционной БД (если она в центре приложения),
например, использовать транзакционный LISTEN/NOTIFY в PostgreSQL.
-
если используем брокер сообщений, то для упрощения отказываемся от гарантированного порядка
доставки сообщений и избегаем exactly once гарантий доставки.
Заключение с цитатой из книги Designing Data Intensive Applications (последняя глава, Stream Processing):
A complex system that works is invariably found to have evolved from a simple system that works.
The inverse proposition also appears to be true: A complex system designed from scratch never works
and cannot be made to work. —John Gall, Systemantics (1975)
К списку выпусков