В каких случаях лучше использовать брокер сообщений для взаимодействия между сервисами
Что проверяют
Понимаете ли вы, когда асинхронность решает задачу, а когда только добавляет инфраструктуру и новые классы ошибок. Хороший ответ содержит и случаи «нужен», и случаи «не нужен». Следом спрашивают про гарантии доставки и про то, как не потерять событие между базой и брокером.
Как отвечать
Брокер оправдан, когда:
- отправителю не нужен ответ сразу: письмо, пересчёт рейтинга, отчёт уходят в фон, пользователь их не ждёт;
- одно событие нужно многим: «заказ создан» читают склад, аналитика и уведомления, а сервис заказов о них не знает;
- нагрузка идёт пиками: очередь сглаживает всплеск, потребители разбирают её со своей скоростью;
- потребитель бывает недоступен: сообщение подождёт в брокере;
- нужен журнал событий: Kafka хранит сообщения заданное время, новый потребитель может перечитать историю.
Синхронный вызов через gRPC или HTTP лучше, когда результат нужен сейчас: проверка баланса, авторизация, данные для ответа пользователю. Request-reply поверх очереди почти всегда хуже прямого вызова.
Выбор: Kafka для потоков событий и высокой пропускной способности, RabbitMQ для очередей задач с маршрутизацией, NATS с JetStream для лёгких сценариев. Клиенты в Go: franz-go или segmentio/kafka-go, rabbitmq/amqp091-go, nats.go.
Назовите механику надёжности: доставка обычно at-least-once, поэтому обработчик идемпотентен; порядок в Kafka гарантирован только внутри партиции; запись в базу и публикация связываются через transactional outbox; сообщения, которые не удаётся обработать, уходят в DLQ.
Где спотыкаются
Пишут в базу и сразу публикуют событие в той же функции. Если сервис упал между шагами, событие потеряно или ушло без записи. Для этого и нужен outbox.
Верят в exactly-once «из коробки». У Kafka эта гарантия действует в рамках её транзакций, а побочные эффекты во внешних системах всё равно требуют дедупликации.
Ставят брокер ради «слабой связанности» двух сервисов одной команды. Связь по контракту сообщений никуда не девается, а отлаживать асинхронный поток сложнее.