Брокеры сообщений
Брокер сообщений — сервис-посредник, который принимает сообщения от одних приложений и доставляет другим, развязывая их во времени и по нагрузке.
Что такое брокер сообщений
Брокер сообщений (message broker) — сервис-посредник, который принимает сообщения от одних приложений и доставляет их другим. Отправитель не знает, кто, где и когда прочитает сообщение: он отдаёт его брокеру и сразу продолжает работу.
Простыми словами это камера хранения между сервисами. Отправитель оставляет посылку и уходит по своим делам, получатель забирает её, когда освободится. Если получатель в этот момент лежит или перегружен, посылка спокойно ждёт на полке, а не теряется и не роняет отправителя.
Зачем он нужен
Без брокера сервис A вызывает сервис B напрямую по HTTP и ждёт ответа. Отсюда три хронические проблемы: B недоступен — падает и A; пик нагрузки — B захлёбывается, а A стоит в ожидании; появился сервис C, которому нужны те же данные — приходится править A.
Брокер разрывает эту связь. A публикует событие «заказ создан» и мгновенно отвечает пользователю; B и C читают событие сами, в своём темпе, и о них A ничего не знает. Очередь заодно работает буфером: при всплеске сообщения копятся у брокера, а не выбивают базу. Такая архитектура называется асинхронной и слабо связанной, и именно она стоит за большинством связок между микросервисами.
Словарь: топик, консьюмер и всё остальное
Топик
Топик (topic, тема) — именованный канал, куда складывают сообщения одного вида: orders.created, user.signup, payments.failed. Продюсер пишет в топик, а не конкретному адресату, и не знает своих читателей. На топик подписываются один или несколько потребителей, и каждый подписчик получает свою копию сообщения — это ключевое отличие топика от очереди, где сообщение достаётся кому-то одному. В Kafka топик дополнительно нарезан на партиции — параллельные части одного потока; в NATS аналог топика называется subject.
Консьюмер
Консьюмер (consumer, потребитель, подписчик) — приложение, которое читает сообщения из топика или очереди и что-то с ними делает: шлёт письмо, списывает деньги, кладёт строку в аналитику. Его противоположность — продюсер (producer, publisher, издатель), который сообщения пишет. Консьюмеров у одного потока может быть много, и работают они в двух режимах: либо делят нагрузку внутри группы (каждое сообщение обрабатывает ровно один из них — так масштабируют обработку), либо читают поток независимо друг от друга (каждый получает всё — так один поток кормит разные подсистемы).
Остальные термины
- Сообщение (message, событие) — единица передачи: тело (обычно JSON или бинарный формат) плюс заголовки и ключ.
- Очередь (queue) — буфер, из которого сообщение забирает один потребитель и после обработки оно исчезает.
- Партиция (partition) — часть топика; определяет и порядок, и предел параллелизма.
- Offset — номер сообщения в партиции; курсор консьюмера, показывающий, докуда он дочитал.
- Ack (acknowledgement) — подтверждение обработки. Пока его нет, брокер считает сообщение недоставленным.
- Consumer lag — отставание консьюмера от продюсера. Главная метрика: растёт lag — не успеваете.
- DLQ (dead letter queue) — отстойник для сообщений, которые не удалось обработать.
Две модели доставки
| Очередь (point-to-point) | Топик (publish/subscribe) | |
|---|---|---|
| Кто получит сообщение | Ровно один потребитель | Каждый подписчик получает копию |
| Зачем | Раздать работу воркерам | Разослать событие всем, кому оно интересно |
| Пример | Сжать видео, отправить письмо | «Заказ оплачен» → склад, почта, аналитика |
| Аналогия | Очередь в кассу | Радиоэфир |
Гарантии доставки
- at-most-once — не больше одного раза, но можно потерять. Ack выдаётся авансом, до обработки. Годится для метрик и телеметрии.
- at-least-once — не потеряем, но можем продублировать. Ack после обработки; упал консьюмер между обработкой и ack — сообщение придёт снова. Режим по умолчанию почти везде.
- exactly-once — ровно один раз. Достижимо лишь внутри контура брокера и с оговорками, стоит заметной производительности.
Практический вывод один: вы почти наверняка живёте на at-least-once, а значит консьюмер обязан быть идемпотентным — повторная обработка того же сообщения не должна менять результат. Обычная реализация: уникальный message_id и проверка «уже обработано» в базе.
Kafka vs RabbitMQ vs NATS
| Kafka | RabbitMQ | NATS | |
|---|---|---|---|
| Модель | Лог с retention | Очереди плюс exchange | Pub/sub; JetStream — лог |
| Сообщение после чтения | Лежит до конца retention | Удаляется после ack | Core: исчезает, JetStream: лежит |
| Перечитать историю | Да | Нет | Только в JetStream |
| Кто маршрутизирует | Консьюмер выбирает топик и offset | Брокер по exchange и routing key | Шаблон subject у подписчика |
| Порядок | Внутри партиции | Внутри очереди | Внутри stream |
| Пропускная способность | Очень высокая | Средняя | Очень высокая |
| Задержка | Миллисекунды | Миллисекунды | Микросекунды в core-режиме |
| Стек и вес | JVM, тяжёлая эксплуатация | Erlang, средняя | Go, один бинарник |
| Берут ради | Потока событий и аналитики | Гибкой раздачи задач воркерам | Скорости и лёгкости, edge и IoT |
Короткое правило выбора. Нужен поток событий, который перечитывают и раздают многим потребителям, — Kafka. Нужна умная раздача задач воркерам с приоритетами, отложенным повтором и маршрутизацией на стороне брокера — RabbitMQ. Нужна лёгкая быстрая шина внутри кластера, request/reply и минимум обслуживания — NATS. Для устройств и слабых каналов есть отдельный протокол — MQTT.
Что ломается на практике
- Растущий lag. Продюсер быстрее консьюмеров. Мониторить нужно именно lag, а не только «жив ли процесс».
- Poison message. Сообщение, на котором консьюмер падает всегда. Без DLQ очередь встаёт колом, а повтор с возвратом в ту же очередь даёт бесконечный цикл.
- Дубликаты. Прямое следствие at-least-once, лечится идемпотентностью.
- Потеря при рестарте. Очередь и сообщения должны быть durable и persistent, иначе перезапуск ноды сотрёт всё.
- Брокер как единая точка отказа. Одиночный узел, поставленный ради отказоустойчивости, её же и убивает: нужны минимум три узла и репликация.
По ресурсам брокер — это диск, память и сеть: держат его рядом с потребителями, потому что сетевая задержка между площадками входит в каждое сообщение.
Связанные термины
- Apache Kafka — брокер-лог, стандарт для потоков событий
- RabbitMQ — классический брокер очередей с маршрутизацией
- NATS — лёгкая шина с микросекундными задержками
- MQTT — протокол обмена сообщениями для устройств и слабых каналов
- Микросервисы и монолит — архитектура, где брокер обязателен
- Redis — часто выступает лёгкой очередью в небольших проектах
Готовы запустить GPU-задачу?
Запустить GPU-сервер