Архитектуру проверяет следующее изменение
- 01ПотребностьЧто нужно изменить
- 02СвязиКакие границы затронуты
- 03ПоставкаКто выпустит и поддержит
В работе с аналитиками и командами я постоянно возвращаюсь к одной мысли: знание названий паттернов ещё не помогает выбрать архитектуру. Полезнее понимать, сколько будет стоить следующее изменение и кто сможет безопасно довести его до production.
Поэтому вместо спора «монолит или микросервисы» я смотрю на две вещи:
- Стоимость изменения — сколько кода, данных, команд и проверок затронет новая потребность.
- Зрелость эксплуатации — умеем ли мы наблюдать, выпускать и восстанавливать несколько независимо работающих компонентов.
Что входит в стоимость изменения
Считать строки кода бессмысленно. Одна строка в схеме данных может потребовать миграции десятка потребителей, а большой локальный рефакторинг не изменить внешний контракт вообще.
На практике стоимость видна в других вопросах:
- сколько модулей и репозиториев нужно изменить;
- сколько команд должны согласовать решение;
- как долго идут тесты и выпуск;
- нужна ли миграция данных;
- можно ли откатить изменение независимо;
- насколько велик радиус инцидента;
- кто владеет результатом после релиза.
Архитектура становится дорогой не из-за размера как такового, а из-за связанности и неясных границ ответственности.
Когда модульный монолит дешевле
Монолит часто даёт короткий путь от идеи до работающей функции: единая поставка, простые локальные вызовы и более доступная общая транзакция в одной базе. Это не обязательство запускать ровно один процесс: у приложения могут быть реплики и фоновые workers. Вынос состояния сессий из процесса упрощает горизонтальное масштабирование, но пределы общей базы и других зависимостей всё равно нужно измерять. Само слово «монолит» не означает низкую производительность или невозможность роста.
Проблемы начинаются, когда модули знают внутренности друг друга, общая база превращается в неформальный API, а любое изменение требует полного регресса. Это аргумент сначала улучшить модульность, а не сразу добавлять сеть.
Я бы сохранял модульный монолит, если:
- доменная модель ещё заметно меняется;
- продукт развивает одна команда или несколько тесно связанных команд;
- единый релиз не создаёт системного узкого места;
- нагрузка растёт примерно одинаково по всей системе;
- требования к доступности и безопасности не требуют отдельных контуров;
- платформенная и дежурная функции пока невелики.
Хороший монолит — не временная неловкость. Для многих продуктов это рациональная конечная архитектура.
Что покупают микросервисы
Микросервисы полезны не потому, что «масштабируются лучше». Они покупают независимость конкретных границ:
- команда может выпускать свой компонент без общего релиза;
- горячую часть системы можно масштабировать отдельно;
- для компонента можно задать отдельные SLO и правила доступа;
- сбой можно локализовать, если зависимости спроектированы на деградацию;
- жизненный цикл домена и его данных получает одного владельца.
За эту независимость платят сетью, таймаутами, повторными запросами, версионированием контрактов, распределённой диагностикой и более сложной согласованностью данных. Если команда не умеет управлять этими расходами, микросервисы увеличат стоимость изменения.
Разные языки программирования — тоже не бесплатная гибкость. Каждый новый стек требует сборки, сканирования, мониторинга, обновлений и людей, которые смогут поддержать его через несколько лет.
Когда выделение сервиса оправдано
Я ищу не мечту о будущем росте, а наблюдаемую проблему:
- У домена есть устойчивая граница и понятный владелец данных.
- Команда регулярно блокируется общим циклом релиза.
- Компонент имеет отличный от остальной системы профиль нагрузки.
- Для него нужен отдельный уровень доступности, безопасности или регуляторного контроля.
- Изоляция действительно уменьшит радиус отказа, а не добавит каскадную зависимость.
Одного признака обычно мало. Если проблема решается границей модуля, очередью задач или отдельной репликой базы, новый сервис может оказаться лишним.
Готова ли команда эксплуатировать решение
До выделения сервисов я проверяю, есть ли у команды:
- автоматизированные сборка, тесты и выпуск;
- метрики, централизованные логи и распределённая трассировка;
- понятные SLO, алерты и дежурство;
- контрактные тесты и правила совместимости схем;
- управление секретами и доступами;
- владелец сервиса, runbook и сценарий отката;
- платформа, которая не заставляет каждую команду собирать всё это заново.
Kubernetes сам по себе эту готовность не обеспечивает. Он запускает контейнеры, но не определяет границы домена и не делает вызовы надёжными.
Как мигрировать без «переписать всё»
Безопасный путь скучнее большой трансформации:
- измерить, где именно изменение или релиз тормозят;
- привести в порядок границы внутри монолита;
- выбрать один компонент с понятным эффектом от отделения;
- зафиксировать контракт и владельца данных;
- обеспечить наблюдаемость, совместимость и откат;
- проверить, снизилась ли реальная стоимость изменения.
Если не снизилась, продолжать дробление по инерции не нужно.
На какие показатели смотреть
Мне полезны не «количество сервисов» и не «процент микросервисности», а:
- время от принятого изменения до production;
- частота и доля неуспешных выпусков;
- время восстановления;
- длительность тестового и релизного цикла;
- доля изменений, требующих участия нескольких команд;
- число инцидентов на границах интеграций.
Архитектура работает, когда бизнес-изменения проходят быстрее без роста операционного риска. Всё остальное — средство.
Из моего Telegram-канала @it_underside.
Ваш ДПУПП
Похожие статьи
RAG для компании: от поиска по документам до полезного ассистента
RAG простыми словами: как устроены поиск и индексация, зачем они нужны рядом с LLM, чем отличаются решения для небольшой команды и enterprise и как получить полезного ассистента.
Сделать аналог — только начало: считаем TCO решения
Как сравнивать продукт, форк, совместимую реализацию и собственную разработку по полной стоимости владения: обновления, эксплуатация, компетенции, риски и выход.
«Как в FAANG» без культа: переносим практики вместе с контекстом
Почему архитектурную практику нельзя копировать отдельно от масштаба, команды и эксплуатационной зрелости. Признаки лишней сложности и вопросы перед внедрением.