Миграция микросервисной платформы
Исходная ситуация
К нам обратились с проектом pro.mylabel.cc, который уже более года находился в эксплуатации.
Основные проблемы:
- регулярные ошибки в production;
- нестабильная бизнес-логика;
- отсутствие централизованной обработки ошибок;
- слабое покрытие тестами;
- утеря базы данных дважды за год;
- сложная и чрезмерно раздробленная микросервисная архитектура;
- высокая стоимость поддержки и невозможность предсказуемого масштабирования.
Проект был построен как набор микросервисов на Node.js/NestJS и частично PHP, каждый со своей отдельной базой данных и связями по UUID без общих внешних ключей.
Для данного масштаба продукта такая архитектура оказалась избыточной и усложняла сопровождение.
Этап 1. Глубокий технический аудит
Мы начали с полного code review и анализа production-логов.
В ходе аудита выявлено:
- отключён строгий режим TypeScript (noImplicitAny, strictNullChecks)
- отсутствует централизованная обработка ошибок (throw new Error, console.log вместо стандартных исключений NestJS)
- практически отсутствует покрытие unit и e2e тестами (тестируется только базовый endpoint)
- бизнес-логика перегружена и нарушает принцип SRP (крупные сервисы и контроллеры)
- секреты частично использовались в Dockerfile и конфигурации
- ошибки в production-логах указывали на необработанные edge-cases и EntityNotFoundError
Главный вывод аудита:
исправление существующей архитектуры потребовало бы сопоставимых трудозатрат с полной переписью backend.
Ключевая архитектурная проблема
Платформа состояла из множества микросервисов:
- auth
- artists
- mylabel
- files
- profiles
- muslink
- notifications
- payments
- tickets
- survey
- statistics
- booking и др.
Каждый сервис имел собственную БД. Связи реализовывались только через UUID без реальных внешних ключей.
Для проекта такого масштаба это создавало:
- сложность поддержки
- риск рассинхронизации данных
- проблемы с транзакционной целостностью
- невозможность корректного восстановления после аварий
Принятое решение
Мы предложили заказчику: Полный отказ от микросервисной архитектуры и перенос всей логики в единый Symfony-монолит с общей PostgreSQL базой данных.
Заказчик поддержал решение.
Фронтенд и UI остались без изменений. API-контракты были сохранены, чтобы переход прошёл безболезненно.
Этап 2. Проектирование монолитной архитектуры
Была создана единая миграция Doctrine, объединяющая все домены в одной PostgreSQL базе.
В монолит перенесены:
- Auth
- Artists
- Releases / Tracks
- Files
- Profiles
- Muslink
- Payments / Subscriptions
- Survey
- Tickets
- Statistics
Все таблицы приведены к единому стилю (snake_case). Настроены реальные внешние ключи и индексы.
Этап 3. Перенос бизнес-логики
В Symfony были реализованы:
- Entity + Repository для всех доменов
- Сервисы с разделением ответственности
- DTO для валидации входящих данных
- Контроллеры, повторяющие старые API-контракты
- JWT-аутентификация
- Symfony Messenger вместо хаотичных очередей
Логика, которая раньше агрегировалась в api-gateway, теперь формируется внутри монолита в одном месте.
Этап 4. Объединение всех баз данных
Одна из самых сложных задач - объединить дампы всех микросервисов в единую БД.
Мы разработали:
- скрипт импорта дампов
- конвертер COPY → INSERT
- фильтрацию данных с учётом FK
- механизм ON CONFLICT DO NOTHING
- автоматическую синхронизацию sequence

Это позволило:
- безопасно объединить разрозненные БД
- сохранить UUID-связи
- избежать дублирования
- восстановить целостность данных
Почему монолит оказался правильным решением
Для данного проекта:
- нет необходимости в независимом масштабировании сервисов
- нет высокой нагрузки, требующей микросервисов
- важна консистентность данных
- критична стабильность
Монолит на Symfony дал:
- единую точку ответственности
- прозрачную архитектуру
- реальную транзакционность
- простоту деплоя
- управляемость
Результат
После миграции:
- устранены production-ошибки
- стабилизирована работа релизов и треков
- исключены рассинхронизации между сервисами
- повышена отказоустойчивость
- обеспечена возможность корректного резервного копирования
- упрощена поддержка
Проект стал технически устойчивым и масштабируемым.
Команда
Руководитель проекта - 1 Backend-разработчики - 2 DevOps - 1
Итог
Этот кейс - пример того, как избыточная микросервисная архитектура может быть вредной для проекта среднего масштаба. Грамотный аудит, честная оценка рисков и архитектурный пересмотр позволили не «латать» систему, а создать устойчивую основу для дальнейшего развития продукта.