В какой-то момент приложение перестаёт общаться только через HTTP. Сервисов становится больше, и нужно передавать сообщения между ними — так, чтобы отправитель не ждал ответа и не падал, если получатель временно недоступен. Тут появляется брокер сообщений.
Самые популярные два: RabbitMQ (реализует протокол AMQP) и Apache Kafka. На первый взгляд они делают одно и то же — принимают и раздают сообщения. Но устроены фундаментально по-разному.
Главное различие: задача или запись в журнале
Вот ключевая разница, из которой вытекает всё остальное.
RabbitMQ относится к сообщению как к задаче. Пришло — кто-то взял — выполнил — сообщение исчезло. Как стикер с поручением на холодильнике: прочитал, выполнил, снял.
Kafka относится к сообщению как к записи в журнале. Пришло — записалось — лежит столько, сколько настроено. Любой читающий сервис в любой момент может начать читать с начала или с любого места. Как бухгалтерская книга: каждая операция навсегда вписана, можно перечитать историю.
Эта разница определяет, какой инструмент подходит для вашей задачи.
Когда нужен RabbitMQ
Представьте интернет-магазин. Пользователь оформил заказ, и нужно отправить ему письмо. Логично поставить задачу в очередь: «отправить письмо пользователю №12345». Один из рабочих процессов возьмёт задачу, отправит письмо и «снимет стикер». Другим задача не нужна — она исполнена.
RabbitMQ создан именно для такого сценария: распределение задач между исполнителями. Брокер сам толкает (push) сообщения к потребителю и управляет очерёдностью.
Типичные случаи для RabbitMQ:
- Отправка писем и уведомлений
- Обработка изображений или документов в фоне
- Вызов сервиса без ожидания ответа (асинхронный RPC)
- Рассылка одного события десяткам сервисов (например, «обновился конфиг»)
- Задачи с дедлайном: «если не обработали за 5 минут — выбросить»
Когда нужна Kafka
Теперь другой сценарий. Тот же интернет-магазин записывает всё, что происходит: «заказ создан», «платёж проведён», «товар отгружен». Через месяц команда аналитики хочет посмотреть все события за этот период. Ещё через месяц запускается ML-сервис — ему тоже нужна вся история.
Если использовать RabbitMQ, история уже удалена. Сообщения исчезли после обработки.
Kafka хранит все записи. Новый сервис может начать читать с самого начала и «догнать» текущий момент. Именно поэтому Kafka называют журналом событий (event log).
Потребители Kafka сами тянут (pull) сообщения в своём темпе. Если один сервис отстал — журнал его дождётся.
Типичные случаи для Kafka:
- Журнал событий с возможностью перечитать историю
- Высокая нагрузка (сотни тысяч событий в секунду)
- Несколько независимых команд читают один поток данных
- Стриминговая аналитика в реальном времени
- Сбор событий из баз данных (CDC через Debezium)
- Event Sourcing — когда события первичны, а состояние вторично
Семь критериев сравнения
1. Природа сообщения
Начните с вопроса: что вы отправляете?
Команда — указание что-то сделать. «Отправить письмо», «обработать файл». После выполнения она больше не нужна. → RabbitMQ.
Событие — факт, что что-то произошло. «Заказ создан», «пользователь зарегистрировался». Может понадобиться многим сервисам, сейчас и в будущем. → Kafka.
2. Порядок сообщений
| RabbitMQ | Kafka | |
|---|---|---|
| Гарантия порядка | Внутри одной очереди | Внутри одной партиции |
| Параллельная обработка с сохранением порядка | Сложно, нужны дополнительные настройки | Естественно через ключ партиции |
В Kafka можно указать ключ (например, userId) — и все события этого пользователя будут идти в одну партицию, строго по порядку. При этом разные пользователи обрабатываются параллельно. В RabbitMQ такого «из коробки» нет.
3. Пропускная способность
Грубые ориентиры на одном узле:
| Пропускная способность | |
|---|---|
| RabbitMQ (надёжный режим) | 30–50 тыс. сообщений/сек |
| Kafka (надёжный режим) | 500 тыс. — 1 млн+ сообщений/сек |
Kafka строилась под огромные объёмы: последовательная запись на диск, пакетная обработка. Для IoT-телеметрии, потоков кликов, сбора логов — Kafka единственный реалистичный вариант. RabbitMQ комфортно работает на тысячах сообщений в секунду.
4. Хранение истории
RabbitMQ: сообщение исчезает после того, как его взяли и подтвердили. Нет возможности перечитать.
Kafka: сообщения хранятся настраиваемое время (по умолчанию 7 дней, можно дольше). Новый сервис, появившийся через неделю, прочитает всё с самого начала.
| Задача | Лучше |
|---|---|
| Перезапустить обработку на старых данных | Kafka |
| Новый сервис должен получить историю | Kafka |
| Аудит и хранение всех событий | Kafka |
| Доставить и забыть | RabbitMQ |
5. Гибкость маршрутизации
RabbitMQ управляет маршрутизацией на уровне брокера. Отправитель публикует в exchange, брокер по правилам раскладывает по очередям. Можно динамически менять кто что получает — отправитель об этом не знает.
Kafka устроена проще: отправитель выбирает топик, читатели подписываются на топик. Добавить нового читателя — просто создать новую группу потребителей без изменений на стороне отправителя.
6. Модель доставки
RabbitMQ (push): брокер сам доставляет сообщения к потребителю. Если потребитель не справляется — брокер включает обратное давление.
Kafka (pull): потребитель сам запрашивает следующую порцию в своём темпе. Если отстал — журнал его дождётся. Брокер не перегружается от медленных потребителей.
Практически: Kafka лучше переносит неравномерную нагрузку. Пик записи в журнал не мешает медленным читателям.
7. Операционная сложность
| RabbitMQ | Kafka | |
|---|---|---|
| Минимальный кластер для производства | 3 узла | 3 брокера + 3 контроллера |
| Мониторинг | Встроенный UI + Prometheus | JMX + специальные инструменты |
| Порог вхождения для команды | Средний | Высокий |
| Кросс-датацентровая репликация | Относительно просто | Требует понимания MirrorMaker 2 |
Kafka — серьёзная операционная инвестиция. Один раз настроить правильно — и она работает годами. Но если команда небольшая и нет опытного администратора, RabbitMQ окажется предсказуемее.
Когда использовать обе вместе
Это не «возьмём обе на всякий случай», а конкретная архитектура.
Сервис получает команды через RabbitMQ (обработать изображение, отправить письмо). После выполнения он публикует факт в Kafka (изображение обработано, письмо отправлено). Аналитика, мониторинг, ML-сервисы читают Kafka и не знают про очередь команд.
HTTP → RabbitMQ (команда) → Сервис → Kafka (событие)
↓
аналитика, мониторинг, ML
Команды атомарны, исчезают после обработки. События накапливаются для истории.
Типичные ошибки выбора
«Возьмём RabbitMQ, потом перейдём на Kafka» — если данные нужны как журнал событий, начинайте с Kafka сразу. Переход — это переписывание логики, не замена клиента.
«Kafka, потому что крупные компании её используют» — крупные компании обрабатывают десятки миллионов событий в секунду. На нескольких тысячах событий в день RabbitMQ проще и дешевле в обслуживании.
«Сделаем очередь задач поверх Kafka» — технически возможно, но Kafka не оптимизирована под короткоживущие задачи. Распределение рабочих задач — это RabbitMQ.
«Будем хранить запросы пользователей в Kafka как в базе данных» — Kafka не база данных. Если нужен произвольный поиск по содержимому — это хранилище событий плюс PostgreSQL или аналог, не сырая Kafka.
Коротко
- RabbitMQ = очередь задач. Сообщение исчезает после обработки. Брокер толкает к потребителю.
- Kafka = журнал событий. Сообщения хранятся и могут быть прочитаны заново. Потребитель тянет в своём темпе.
- Выбирайте RabbitMQ для распределения задач между исполнителями, асинхронного RPC, гибкой маршрутизации.
- Выбирайте Kafka для хранения истории событий, высокой нагрузки, стримингового анализа.
- Порядок событий по ключу в Kafka встроен; в RabbitMQ требует дополнительных усилий.
- Kafka операционно сложнее — оправдана, когда действительно нужны её возможности.
- Обе вместе — не «на всякий случай», а конкретный паттерн: RabbitMQ для команд, Kafka для событий.
Что почитать дальше
- Протокол AMQP — как устроена модель доставки RabbitMQ.
- Messaging-паттерны через AMQP — work queue, pub/sub, RPC, идемпотентность.
- Распределённые паттерны — Saga, Outbox, Idempotent Consumer (применимы к обоим брокерам).