Какие сервисы нужны для обработки заказа на продукт и как они взаимодействуют
Что проверяют
Умеете ли вы спроектировать распределённый процесс, а не только нарисовать пять прямоугольников. Следом Go-разработчика спрашивают про реализацию: как передаются таймауты, как событие публикуется без потерь и что делает консьюмер при повторной доставке.
Как отвечать
Базовый набор: Order (заказ и статусы), Inventory (остатки и резервы), Payment (платёжный провайдер), Delivery (отправления) и Notification (уведомления). У каждого своя база, чужие таблицы никто не читает.
Опишите поток. Клиент создаёт заказ, Order синхронно резервирует товар в Inventory и отвечает. Дальше процесс идёт событиями: OrderCreated, PaymentSucceeded или PaymentFailed, ShipmentCreated. При ошибке сага запускает компенсации: снять резерв, отменить заказ, вернуть деньги.
Реализация на Go:
- синхронные вызовы: gRPC с контрактами в protobuf, у каждого вызова дедлайн через
context.WithTimeout, контекст пробрасывается дальше по цепочке. Параллельные запросы удобно собирать черезerrgroup; - брокер: Kafka через
franz-goилиsegmentio/kafka-go, либо NATS JetStream. Offset коммитится после обработки сообщения, а не до; - outbox: заказ и запись в таблицу
outboxделаются в одной транзакцииpgx.Tx, отдельный воркер читает таблицу и публикует; - идемпотентность: ключ для оплаты, таблица обработанных
event_idу консьюмера, уникальные ограничения в базе; - оркестрация: для сложной саги Temporal с Go SDK берёт на себя повторы, таймеры и состояние процесса;
- устойчивость: повторы с экспоненциальной задержкой и джиттером, circuit breaker вроде
sony/gobreaker, graceful shutdown черезsignal.NotifyContext.
Статусы заказа держите конечным автоматом, тогда запоздавшее событие не вернёт оплаченный заказ в «создан».
Где спотыкаются
Публикуют событие горутиной после коммита, «чтобы не ждать». При падении процесса оно теряется бесследно.
Вызывают соседние сервисы с context.Background() без дедлайна. Один зависший сервис держит горутины и соединения, пока не кончатся ресурсы.
Верят в exactly-once доставку. Kafka даёт её только в цепочке чтения и записи внутри себя, а на границе с базой и внешним API нужна идемпотентность.