Проект представляет собой систему из нескольких микросервисов для обработки заказов и платежей. Основной упор сделан на асинхронное взаимодействие, отказоустойчивость и гарантию целостности данных при высоких нагрузках.
Стек: Python (FastAPI), PostgreSQL, RabbitMQ, Redis, React.
Весь проект полностью докеризирован.
-
Клонирование Перейдите в папку с проектом.
-
Сборка и запуск
docker compose up --build
-
Ожидание старта
Интерфейс доступен по адресу: http://localhost:3000
- Введите User ID (любое число, например,
1) в шапке сайта. - Перейдите на вкладку «💰 Счет» и нажмите «+ Создать счет».
- Пополните баланс на любую сумму.
- Перейдите на вкладку «📦 Заказы» и создайте заказ.
- Наблюдайте за сменой статуса (
NEW->FINISHED) и всплывающими уведомлениями.
Документация API Gateway: http://localhost:8000/docs
Панель управления брокером: http://localhost:15672
- Логин:
guest - Пароль:
guestМожно мониторить очередиorders.to_payиpayment.results.
Система разбита на независимые компоненты, как и требовалось в задании.
- API Gateway: Единая точка входа. Проксирует HTTP-запросы в нужный сервис и держит WebSocket-соединения с клиентами.
- Orders Service: Управление заказами. Работает в двух инстансах для демонстрации балансировки нагрузки.
- Payments Service: Управление счетами и транзакциями.
Вместо прямых HTTP-вызовов между сервисами используется RabbitMQ.
-
Гарантия доставки: При создании заказа в
Orders Service, он сразу создаётся в одной транзакции с заказом сохраняется запись в таблицуoutbox_messages. Отдельный фоновый процесс (worker_outbox.py) вычитывает эти записи и отправляет их в брокер. Это гарантирует, что даже если брокер упадет в момент заказа, сообщение не потеряется и уйдет позже. -
Идемпотентность: В
Payments Serviceпри получении сообщения сначала проверяется его уникальный ID в таблицеinbox_messages. Если сообщение уже обрабатывалось, оно игнорируется. Это обеспечивает семантику exactly-once.
Чтобы баланс не уходил в минус и не было "гонки" при одновременных запросах, используется пессимистичная блокировка БД:
SELECT ... FOR UPDATE
Это держит строку счета заблокированной до конца транзакции списания или пополнения.
Реализована схема с Redis Pub/Sub.
- Когда статус заказа меняется, воркер публикует событие в Redis.
- API Gateway (и другие инстансы) слушают Redis и пересылают уведомление конкретному пользователю в WebSocket.
- Это позволяет пользователю получать пуш-уведомления независимо от того, к какому инстансу бэкенда он подключен.
- Реализован красивый UI на React + CSS (Dark mode, анимации, скелетоны).