Правило:
Нельзя резать, не определив границы. Начинать нужно с бизнес-логики и данных, а не с кода
Качественный сервис после распила обладает:
💙слабой зависимостью (loose coupling) — изменения не ломают соседей
💙высокой внутренней связностью (high cohesion) — сервис решает одну бизнес-задачу
Стратегии
💙 Декомпозиция по бизнес-доменам
Основана на Domain-Driven Design
💙Каждый сервис = один Bounded Context: собственная логика и данные
💙Границы определяются бизнес-процессами, а не слоями кода
💙 Пошаговый переход
1. Анализ предметной области, выделение контекстов Например, где заканчивается работа склада и начинается работа логистики
2. Определить владельцев данных. Н-р, какие таблицы в монолитной БД принадлежат какому контексту
3. Запретить прямой доступ к «чужим» таблицам
4. Выделить API
5. Отдельный деплой
💙 Пример
Каталог (товары, цены) и "Заказы" (корзина, оформление). Их можно разделятьЗаказы хранят цену на момент покупки и не зависят от текущей цены каталога❤️Не применять
♥️плохо формализован домен и нет четких бизнес-процессов
♥️ нет владельца продукта
♥️ часто меняющиеся границы (MVP)
💙 Strangler Fig
Безопасный способ рефакторинга "на ходу", когда монолит нельзя останавливать
💙Перед монолитом ставится маршрутизатор: API Gateway или обратный прокси (nginx, HAProxy)
💙Новая функциональность создаётся в микросервисах, старая постепенно удаляется.
💙 Пошаговый переход
1. Выбрать изолированный use-case
2. Реализовать его как сервис
3. Настроить маршрутизацию
4. Переключить трафик
5. Удалить старую реализацию
💙 Пример
Личный кабинет переносится по частям: сначала профиль, затем смена пароля, затем всё остальное. Монолит постепенно очищается❤️Не подходит
♥️если нужен быстрый полный переход
♥️ монолит невозможно маршрутизировать
💙 Декомпозиция по данным (Database per Service)
Не самостоятельная стратегия, а обязательное условие микросервисов
Каждый сервис владеет собственной БД. Общих таблиц нет. Доступ к данным — только через API
Подходы
💙разные схемы в одной СУБД
💙физически отдельные БД
💙копии данных + события
💙Event-driven синхронизация
💙 Пошаговый переход
1. Определить владельца таблиц
2. Запретить cross-schema JOIN
3. Выделить БД
4. Перевести взаимодействие через API
5. Настроить события при необходимости
Пример
Order Service получает собственную БД. Остальные сервисы работают с заказами только через API❤️Не применять
♥️требуются жёсткие распределённые транзакции
♥️нет инфраструктуры событий
💙 Декомпозиция по нагрузке (Performance-driven)
Выносится компонент, создающий нагрузку
💙 Пошаговый переход
1. Найти узкое место (метрики, профилирование)
2. Выделить код
3. Перевести в асинхронный режим
4. Добавить кэширование
💙 Пример
Поиск товаров выносится в сервис с собственным Elasticsearch и масштабируется отдельно
❤️Не применять
♥️если проблема в плохом SQL, а не в архитектуре
♥️нагрузка не критична
💙 Декомпозиция по частоте изменений
Выносится модуль, который меняется чаще остальных, чтобы ускорить релизы
💙 Пошаговый переход
1. Анализ истории коммитов
2. Выделение часто меняющегося модуля
3. Отделение данных
4. API и независимый деплой
💙 Пример
Блок
Акции и предложения обновляется ежедневно. Его вынос позволяет деплоить изменения без затрагивания ядра системы❤️ Не применять
Частые изменения вызваны хаосом требований
📎 Материалы
1. Шпаргалка по миграции монолита на микросервисы
2. Когда и как переходить с монолита на микросервисы. Предпосылки и общие понятия
3. Архитектура микросервисов: Разрушение монолита
4. Как НЕ надо распиливать монолит
5. Микросервисная архитектура: от монолита к гибкой системе
📚 Книги
Сэм Ньюмен - Создание микросервисов
#архитектура
➿➿➿➿➿➿➿➿
🧑🎓 Больше полезного в базе знаний по системному анализу