Зачем создавать отдельный сервис воркер для аналитики вместо обработки в ордер сервисе
Что проверяют
Умеете ли вы отделять критичный путь от вспомогательной работы и понимаете ли, какую цену платите за асинхронность. Следом обычно спрашивают, как гарантировать, что событие о заказе не потеряется, и что будет, если воркер обработает его дважды.
Как отвечать
Главный аргумент в разных требованиях к двум задачам:
- задержка и доступность: оформление заказа должно отвечать быстро и не зависеть от аналитики. Если ClickHouse или внешний трекер тормозит, заказы вставать не должны;
- профиль нагрузки: аналитика работает пачками, агрегирует, тяжело пишет. Её удобно масштабировать отдельно и обрабатывать с задержкой;
- изоляция отказов: воркер упал, события копятся в брокере, после рестарта он дочитывает их с сохранённого offset.
Схема обычно такая. Сервис заказов в одной транзакции пишет заказ и событие в таблицу outbox, отдельный процесс публикует события в Kafka, NATS JetStream или RabbitMQ. Воркер в consumer group читает топик, партиционированный по order_id, пишет в хранилище пачками и коммитит offset только после успешной записи. В Go для Kafka берут franz-go или segmentio/kafka-go.
Доставка при этом at-least-once, поэтому обработка должна быть идемпотентной: дедупликация по event_id или движок вроде ReplacingMergeTree в ClickHouse.
Назовите и минусы: eventual consistency, ещё один сервис в мониторинге, контракт событий, который надо версионировать (Protobuf, schema registry), лаг консьюмера как отдельная метрика. Для небольшой системы честный ответ: хватит outbox-таблицы и фоновой горутины, которая её вычитывает, а отдельный воркер нужен, когда нагрузка или требования к надёжности это оправдывают.
Где спотыкаются
Предлагают просто go sendAnalytics(ctx, order) в обработчике. При рестарте пода события теряются, число горутин ничем не ограничено, а ctx запроса отменяется сразу после ответа клиенту, и отправка обрывается.
Публикуют событие после коммита отдельным вызовом. Между коммитом и отправкой процесс может упасть, это классическая проблема dual write, её и решает outbox.
Забывают про повторы и порядок. Без идемпотентности повторная доставка удвоит выручку в отчёте.