Короткий ответ
Границы сервисов стоит проводить по bounded context (устойчивым бизнес-возможностям и владению данными), а не по техническим слоям или текущей оргструктуре; выбор конкретных границ зависит от стабильности домена, профиля нагрузки и зрелости команды — универсального правильного разбиения не существует.
Как это работает подробнее
Домен анализируют через карту бизнес-процессов и данных, ищут «швы» — зоны с низкой связанностью и высокой внутренней согласованностью (например, «каталог» слабо связан с «биллингом» по данным и темпу изменений).
Слишком крупные границы (мало сервисов) сохраняют часть проблем монолита (совместные деплои, связанность), но проще в эксплуатации; слишком мелкие границы дают высокую автономию команд, но взрывообразно увеличивают операционную сложность (сетевые вызовы, распределённые транзакции, мониторинг) и могут быть избыточны для текущего масштаба. Критерий выбора — соотносить стоимость координации при текущих границах со стоимостью операционной сложности при более мелком разбиении, и пересматривать границы по мере того, как домен и команда созревают.
Пример кода
Вариант A: Order Service включает заказы + оплату + доставку (крупная граница)
— меньше сетевых вызовов, но любое изменение оплаты требует релиза всего Order Service
Вариант B: отдельные Order, Payment, Shipping Service (мелкая граница)
— независимые релизы, но заказ теперь требует Saga между тремя сервисами
и обработки частичных отказовЧто использовать на практике
- Практика. Критерии выбора: частота совместных изменений (если два модуля почти всегда меняются вместе — граница проведена неверно), различие в требуемом масштабировании/SLA, зрелость команды для операционной сложности отдельного сервиса.
Подводные камни
- Риск. Проводить границы по оргструктуре «как есть сейчас» без проверки её устойчивости; разбивать по техническим слоям (отдельный «сервис для БД») вместо бизнес-возможностей.