Сервис выделяют ради независимого деплоя, масштаба и отказов, а не потому что «так модно». Distributed monolith — сеть и операционка микросервисов при общей базе и lock-step релизах.
Проектирование сервисов architecture собеседование
Монолит: один деплой, одна база, локальные вызовы функций. Проще транзакции. Проще трассировка. Один набор миграций. Цена: команда и нагрузка делят судьбу. Отказ модуля может утянуть весь процесс.
Микросервис оправдан, когда релиз, данные и отказ действительно независимы. Своё хранилище. Свой цикл жизни. Свой SLO.
Если при клике пользователя вы синхронно зовёте пять соседей и пишете в те же таблицы — вы купили латентность и CAP, не автономность.
Пример. Команда из пяти человек режет «витрину», «заказ» и «уведомления» в три репозитория, но все пишут в одну Postgres. Релизы всё равно вместе. Это не микросервисы. Это монолит с сетевой таксой.
Когда резать
- Разные циклы жизни: рендер PDF можно катить ежедневно, checkout — раз в неделю с жёстким регрессом.
- Разный масштаб: пик генерации отчётов не должен требовать столько же реплик, сколько витрина.
- Явный bounded context: другой язык данных, другие инварианты, другой SLO.
- Не резать, пока команда одна и домен не устоялся. Стоимость сети, наблюдаемости и дублей контрактов обычно выше выигрыша.
Distributed monolith
Симптомы: общая БД «по таблицам на сервис». Обязательный синхронный вызов цепочки на один клик. Релизы только вместе. Общая библиотека с миграциями.
Много процессов и репозиториев создают иллюзию архитектуры. На деле вы не можете выкатить сервис A без B и миграции в той же базе.
Модульный монолит честнее: границы в пакетах, запрет импорта «через голову», иногда отдельные схемы. Когда контекст стабилизируется, вынос модуля — перенос пакета за RPC плюс своё хранилище.
// Клиент нажал «купить». Один запрос, пять round-trip и общая БД.
//
// browser
// |
// v
// order-svc --SQL--> public.orders, public.users, public.stock
// | HTTP
// |----------> billing-svc --SQL--> public.accounts (та же Postgres)
// |----------> stock-svc --SQL--> public.stock (те же строки)
// +----------> notify-svc --SQL--> public.users
//
// Выкатить stock-svc без миграции orders нельзя.
// Падение billing роняет checkout.
// Это не независимость.
Синхронная паутина плюс общая БД — distributed monolith, сколько бы репозиториев ни было.
Типичная ошибка
Резать по слоям: «сервис БД», «сервис валидации» вместо bounded context. Получаете болтливую сеть на каждый use case и общую модель данных. Число сервисов само по себе ничего не гарантирует.
На собеседовании
Критерий — независимый деплой и независимые данные. Назовите, какой отказ изолируется. Модульный монолит — нормальный ответ, пока домен сырой. Distributed monolith — сеть плюс общая БД и lock-step.