Какие сервисы нужны для обработки заказа на продукт и как они взаимодействуют
Что проверяют
Умеете ли вы разбить предметную область на сервисы с чёткими границами и связать их так, чтобы заказ не терялся, а деньги не списывались дважды. Следом обычно спрашивают: что будет, если оплата прошла, а сервис заказов упал до записи статуса.
Как отвечать
Сначала задайте пару уточняющих вопросов: масштаб, внешний ли платёжный провайдер, нужен ли резерв товара. Потом назовите сервисы, у каждого своя база:
- Order: создаёт заказ и ведёт его конечный автомат
created,reserved,paid,shipped,cancelled; - Inventory: остатки и резервы. Резерв живёт с TTL, чтобы брошенные заказы не держали товар;
- Payment: общается с платёжным провайдером и принимает его вебхуки;
- Delivery: создаёт отправление у службы доставки и следит за статусом;
- Notification: письма, SMS и пуши по событиям остальных сервисов.
Синхронно, по HTTP на FastAPI с httpx или по gRPC, идёт только то, чего ждёт пользователь: создание заказа и проверка остатков. Остальное идёт событиями через Kafka или RabbitMQ (aiokafka, aio-pika, для фоновых задач Celery).
Оформление заказа это сага. При хореографии сервисы реагируют на события друг друга. При оркестрации Order или отдельный оркестратор, например на Temporal, явно вызывает шаги и при сбое запускает компенсации: оплата не прошла, значит снять резерв и отменить заказ.
Два обязательных приёма надёжности:
- transactional outbox: заказ и событие о нём пишутся в одной транзакции SQLAlchemy, а отдельный процесс публикует событие в брокер;
- идемпотентность: ключ идемпотентности у запроса оплаты и дедупликация у потребителя, потому что брокер гарантирует доставку «хотя бы раз».
Где спотыкаются
Строят синхронную цепочку HTTP-вызовов через все пять сервисов. Доступность перемножается, и падение уведомлений ломает оформление заказа.
Пытаются добиться согласованности одной распределённой транзакцией или общей базой. Ожидаемый ответ: согласованность в конечном счёте и компенсации.
Публикуют событие в брокер сразу после commit(). Если процесс упадёт между двумя шагами, событие потеряется, и от этого как раз спасает outbox.