Чек-лист по распилу монолита

Почему вообще нужно «распиливать»?

  • Командная независимость. Чем меньше команд трогают один и тот же код, тем быстрее идут релизы.
  • Масштабируемость. У разных подсистем разные RPS-пики и SLA. Лучше разделить функционалость, чтобы было проще масштабировать.
  • Надёжность. Отказ одного сервиса не валит всю систему, если границы корректно очерчены.

Антипример из практики: в одной финтех-компании маркетинговая рассылка была частью монолита. Когда команда маркетинга запустила A/B-эксперимент, Redis-кэш рассылки резко вырос и «съел» всю доступную RAM. Итог ‒ 15-минутный даунтайм платёжного API, хотя письма к платежам вообще не относились.

Шаг 1. Анализ зон ответственности
  1. Погружаемся в модули монолита. Помечаем, какая часть кода отвечает за какой бизнес-домен: «Профиль», «Платежи», «Лента», «Каталог»…
  2. Смотрим данные. Изучаем, какие таблицы читает/пишет каждый модуль. Если таблица используется повсеместно, она, скорее всего, «прозвенит» тревогу при миграции.
  3. Проверяем зависимости. Любой прямой импорт из «чужого» пакета фиксируем ‒ это потенциальная «склейка» доменов.
Шаг 2. Разделяем базы данных по шагам
Ступени Что делаем Зачем Инструменты
Шаг 1 Schema Domains – группируем таблицы по доменам в отдельные схемы Упрощаем миграцию и права доступа schema_name.table в PostgreSQL
Шаг 2 Query Watcher – следим за кросс-доменными JOIN-ами. Query Watcher —инструмент, который анализирует логи БД и определяет, какие запросы пересекают границы доменов. Находим «утечки» границ PgHero, pgbouncer-stats, самописный скрипт на Python
Шаг 3 Application-Level JOINs Убираем «сквозные» SQL-JOIN-ы ‒ собираем данные в коде через API REST / gRPC + агрегирующий слой
Шаг 3. Стартовая партия микросервисов
  1. Core-сервисы — аутентификация, авторизация, биллинг.
  2. Инфраструктурные сервисы — работа с шардингом, feature-flags, рассылки.
  3. Правило зависимости: монолит → сервис, но никогда наоборот. Так мы не создаём Distributed Monolith.
Шаг 4. Подчищаем хвосты
  • После каждого «выноса» удаляем из монолита мёртвый код и устаревшие модели.
  • Запускаем регрессионные тесты, чтобы убедиться, что монолит всё ещё собирается и деплоится.
  • Обновляем документацию и диаграммы ‒ архитектура должна быть самодокументированной.