Как осуществлять миграцию с монолита на микросервисы на FastAPI
Что проверяют
Понимаете ли вы, что миграция это прежде всего разделение данных и границ ответственности, а FastAPI лишь инструмент для новых сервисов. Следом спрашивают, как вы разделите общую базу и что станет с транзакцией, которая раньше трогала две таблицы, а теперь два сервиса.
Как отвечать
Начните с причины: разные требования к масштабированию, независимые релизы команд, изоляция отказов. Если причины нет, модульный монолит дешевле.
Каркас миграции:
- границы: сервисы выделяют по бизнес-областям (bounded context из DDD), а не по техническим слоям. Первым берут модуль с понятными границами и малым числом связей;
- strangler fig: перед монолитом ставят прокси или API gateway (nginx, Traefik), новые пути уходят в FastAPI-сервис, старые остаются в монолите. Откат это смена маршрута;
- данные: у каждого сервиса своя схема или база и свои миграции Alembic. Пока таблицы общие, получается распределённый монолит;
- консистентность: вместо общей транзакции саги и события. Чтобы событие не потерялось, используют transactional outbox: запись и событие в одной локальной транзакции, отправку в Kafka или RabbitMQ делает отдельный процесс;
- взаимодействие: синхронно через
httpx.AsyncClientс явными таймаутами и повторами только идемпотентных операций, асинхронно через брокер. Контракты берут из OpenAPI, который FastAPI генерирует сам; - наблюдаемость: до переноса первого модуля. Сквозной trace id через OpenTelemetry, метрики, общие логи.
В самом FastAPI следите за асинхронностью: синхронный драйвер базы внутри async def блокирует цикл событий. Берите асинхронный драйвер (asyncpg, SQLAlchemy 2.0 в async-режиме) или обычный def, который FastAPI выполнит в пуле потоков.
Где спотыкаются
Режут монолит на сервисы, но оставляют одну общую базу. Любое изменение схемы снова требует согласованного релиза всех сервисов.
Переписывают всё разом с нуля. Такой проект месяцами не приносит пользы, а монолит тем временем продолжают дорабатывать.
Называют CQRS решением проблемы данных. CQRS разделяет модели чтения и записи, но не отвечает на вопрос, кто владеет данными и как сохранить согласованность между сервисами.