Перейти к основному содержимому

Способы распила монолита на микросервисы

Главное правило:

Нельзя резать, не определив границы. Начинать нужно с бизнес-логики и данных, а не с кода.

Качественный сервис после распила обладает:

  • Слабой зависимостью (loose coupling) — изменения не ломают соседей.
  • Высокой внутренней связностью (high cohesion) — сервис решает одну бизнес-задачу.

Когда пора делить

  • Команда > 10–15 человек, конфликты в коде.
  • Релизы блокируют друг друга.
  • Модули развиваются с разной скоростью.
  • Нет независимого масштабирования.
  • Разные требования по отказоустойчивости.

Когда не стоит

  • Команда небольшая
  • Нет автотестов, CI/CD, мониторинга.
  • Простой домен и нет DevOps-практики.

Способы распила

1. Декомпозиция по бизнес-доменам

Основана на Domain-Driven Design.

Каждый сервис = один Bounded Context: собственная логика и данные. Границы определяются бизнес-процессами, а не слоями кода.

Пошаговый переход

  1. Анализ предметной области, выделение контекстов. Например, где заканчивается работа склада и начинается работа логистики
  2. Определить владельцев данных. Н-р, какие таблицы в монолитной БД принадлежат какому контексту
  3. Запретить прямой доступ к «чужим» таблицам.
  4. Выделить API.
  5. Отдельный деплой.

Пример

"Каталог" (товары, цены) и "Заказы" (корзина, оформление). Их можно разделять. "Заказы" хранят цену на момент покупки и не зависят от текущей цены каталога.

Плюсы и минусы

  • Автономность команд.
  • Независимое масштабирование.
  • Архитектурная чистота.

— Сложно определить границы.
— Риск распределённого монолита.
— Сложность межсервисных запросов.

Не применять

  • Плохо формализован домен и нет четких бизнес-процессов
  • Нет владельца продукта.
  • Часто меняющиеся границы (MVP).

2. Strangler Fig

Безопасный способ рефакторинга "на ходу", когда монолит нельзя останавливать.

Перед монолитом ставится маршрутизатор: API Gateway или обратный прокси (nginx, HAProxy). Новая функциональность создаётся в микросервисах, старая постепенно удаляется.

Пошаговый переход

  1. Выбрать изолированный use-case.
  2. Реализовать его как сервис.
  3. Настроить маршрутизацию.
  4. Переключить трафик.
  5. Удалить старую реализацию.

Пример

"Личный кабинет" переносится по частям: сначала профиль, затем смена пароля, затем всё остальное. Монолит постепенно очищается.

Плюсы и минусы

  • Минимальный риск.
  • Возможность остановиться.
  • Простой откат.

— Долго и задваивается логика.
— Сложность синхронизации данных.

Не подходит

  • Если нужен быстрый полный переход.
  • Монолит невозможно маршрутизировать.

3. Декомпозиция по данным (Database per Service)

Не самостоятельная стратегия, а обязательное условие микросервисов. Каждый сервис владеет собственной БД. Общих таблиц нет. Доступ к данным — только через API.

Подходы

  • Разные схемы в одной СУБД.
  • Физически отдельные БД.
  • Копии данных + события.
  • Event-driven синхронизация.

Пошаговый переход

  1. Определить владельца таблиц.
  2. Запретить cross-schema JOIN.
  3. Выделить БД.
  4. Перевести взаимодействие через API.
  5. Настроить события при необходимости.

Плюсы и минусы

  • Чёткие границы.
  • Нет скрытых зависимостей.
  • Независимое масштабирование.

— Нет межсервисных ACID-транзакций.
— Сложнее аналитика.

Не применять

  • Требуются жёсткие распределённые транзакции.
  • Нет инфраструктуры событий.

Пример

Order Service получает собственную БД. Остальные сервисы работают с заказами только через API.

4. Декомпозиция по нагрузке (Performance-driven)

Описание

Выносится компонент, создающий нагрузку.

Пошаговый переход

  1. Найти узкое место (метрики, профилирование).
  2. Выделить код.
  3. Перевести в асинхронный режим.
  4. Добавить кэширование.

Пример

Поиск товаров выносится в сервис с собственным Elasticsearch и масштабируется отдельно.

Плюсы и минусы

  • Быстрый эффект.
  • Изолированное масштабирование.
  • Минимальный рефакторинг.

— Не решает архитектурные проблемы.
— Риск хаотичной структуры.

Не применять

  • Например, если проблема в плохом SQL, а не в архитектуре.
  • Нагрузка не критична.

5. Декомпозиция по частоте изменений

Описание

Выносится модуль, который меняется чаще остальных, чтобы ускорить релизы.

Пошаговый переход

  1. Анализ истории коммитов.
  2. Выделение часто меняющегося модуля.
  3. Отделение данных.
  4. API и независимый деплой.

Пример

Блок "Акции и предложения" обновляется ежедневно. Его вынос позволяет деплоить изменения без затрагивания ядра системы.

Плюсы и минусы

  • Ускорение time-to-market.
  • Снижение рисков релиза.

— Требует чётких границ.
— Возможна сильная синхронная зависимость от монолита.

Не применять

Частые изменения вызваны хаосом требований.

6. Тактический

Обобщение подходов по нагрузке и изменяемости. Выносится то, что прямо сейчас создаёт боль.

Процесс

  1. Найти "бутылочное горлышко".
  2. Изолировать.
  3. Перевести в асинхронный режим.

Пример

Генерация годового отчёта вынесена в отдельный сервис. Пользователь получает уведомление о готовности, монолит не блокируется.

Плюсы и минусы

  • Быстрый результат.
  • Минимальные инвестиции.

— Риск зоопарка сервисов.
— Не формирует целостную архитектуру.

Не использовать

Как единственную долгосрочную стратегию.


Сводная таблица

СтратегияКогда применятьГлавный плюсГлавный минусСложность
По доменамЗрелый продуктЧистая архитектураСложный анализВысокая
StranglerНельзя остановить монолитНизкий рискДолгая миграцияСредняя
По даннымПри любом распилеЧёткие границыПотеря ACIDВысокая
По нагрузкеСистема не выдерживаетБыстрый эффектЛокальное решениеНизкая
По изменениямЧастые релизы одного модуляУскорениеРиск неверных границСредняя
ТактическаяЕсть конкретная больБыстроФрагментацияНизкая

Материалы

  1. Шпаргалка по миграции монолита на микросервисы
  2. Проблемы терминологии — loose coupling and high cohesion
  3. Когда и как переходить с монолита на микросервисы. Предпосылки и общие понятия
  4. Как НЕ надо распиливать монолит
  5. Как мы распилили монолит. Часть 1
  6. Интервью с Марселем Ибраевым о распиле монолита или «Успех распила монолита – грамотный менеджмент»
  7. Вся правда о переходе с монолита на микросервисы, когда у тебя сеть из десятков тысяч магазинов: опыт Х5 Tech
  8. Архитектура микросервисов: Разрушение монолита
  9. Как перейти от монолита к микросервисам без сложностей и рисков? Четыре проверенных паттерна
  10. Как мы монолит пилили
  11. Микросервисная архитектура: от монолита к гибкой системе (да, опять)
  12. Разбиваем монолит на микросервисы
  13. Как распилить монолит: о микросервисной архитектуре веб-приложений
  14. Почему в InVision затаскивают микросервисы обратно в монолит
  15. Основные паттерны микросервисной архитектуры: Strangler Fig, API Gateway, Service Mesh и другие
  16. Аналитика микросервисов. Практический опыт аналитика в enterprise

Видео

  1. Сергей Бондарчук — Распил монолита на микросервисы: создание команды, выбор архитектуры и технологий
  2. Топ ошибок при переходе с монолита на микросервисную архитектуру // Курс «Microservice Architecture»
  3. Как пилить монолит на микросервисы? Механизмы интеграции.
  4. Реальная история распила монолита в Яндекс Еде / Коля Митрофанов, Яндекс Еда
  5. Способы разделения микросервисов на компоненты // Демо-занятие курса " Software Architect"

Конференции

  1. ArchDays 2020 • Распил монолита в Леруа Мерлен • Павел Юркин (Leroy Merlin)
  2. ArchDays 2020 Strangler Fig: Эволюция архитектуры от монолита к микросервисам глазами системного аналитика

Книги

Сэм Ньюмен. Создание микросервисов