Монолит, микросервисы или модульный монолит: что выбрать

AnnaKis

New member
За семь лет работы я успел поучаствовать в трёх переездах архитектуры, и каждый раз мы были уверены, что именно теперь-то выбрали правильный путь. Начинал я в маленьком стартапе, где весь продукт жил в одном репозитории и одном большом монолите. Нас было двое разработчиков, и честно скажу: это был счастливейший период в моей карьере. Мы деплоили одной командой, отлаживали всё в одном процессе, а новичок разбирался в системе за неделю. Монолит тогда не мешал нам расти, а наоборот спасал: мы не тратили ни минуты на сетевые взаимодействия, очереди и распределённые транзакции, а просто писали код, который приносил деньги.

Потом продукт вырос, команда — до пятнадцати человек, и кто-то на очередном ретро авторитетно заявил, что монолит себя изжил и пора идти в микросервисы. Мы, как водится, вдохновились конференциями и за полгода распилили систему на двадцать сервисов. Это было больно. Деплой усложнился настолько, что релиз превращался в многочасовой ритуал, логи размазались по десяткам мест, а отладка одного пользовательского сценария требовала поднять половину инфраструктуры локально. Бизнес-фичи при этом стали выходить медленнее, хотя формально независимые команды должны были ускорить нас. Я до сих пор вспоминаю тот проект как наглядный пример того, что микросервисы решают организационные проблемы, а не технические, и брать их нужно тогда, когда эти проблемы уже реально болят.

На третьем проекте мы поступили иначе. Сначала долго спорили, потом сели и честно посчитали: сколько команд, сколько релизов в неделю, насколько болезненно развернуть всё целиком. И пришли к модульному монолиту — одной кодовой базе, но с жёсткими внутренними границами между модулями и запретом лазить напрямую в чужие таблицы. Каждый модуль имел свой публичный интерфейс, свои миграции и свою зону ответственности, а общение шло через явные контракты. Деплой остался одним, зато код не превращался в большой шар грязи, и любой модуль можно было относительно спокойно вынести в отдельный сервис, когда придёт время.

Главный вывод, который я вынес из всех трёх заходов, прост: архитектуру выбирают не по моде, а по масштабу и структуре команды. Если в проекте до пяти-семи разработчиков и один продуктовый поток, чистый монолит — почти всегда лучший выбор, и уж точно не стоит стесняться этого решения. Микросервисы оправданы, когда у вас несколько команд, которые мешают друг другу в одном репозитории, когда нужны независимые релизы и разное масштабирование под разную нагрузку, и когда есть кому заниматься инфраструктурой, мониторингом и трассировкой. Модульный монолит — это золотая середина для тех, кто уже перерос наивный монолит, но ещё не готов платить полную цену распределённой системы.

Отдельно скажу про границы. Многие думают, что дело в количестве сервисов, а на самом деле всё решают границы ответственности. Можно иметь десять сервисов, которые дёргают друг друга по кругу и деплоятся только вместе, — и это будет самый настоящий распределённый монолит, только медленнее и с сетью посередине. А можно иметь одну кодовую базу, где модули общаются через понятные интерфейсы, и жить спокойно годами. Поэтому я всегда советую сначала навести порядок в границах внутри монолита, а уже потом думать о выделении сервисов. Если границы плохие, микросервисы их не исправят, а только увеличат масштаб проблемы.

Практические рекомендации читателям у меня такие. Начните с монолита или модульного монолита, если только у вас нет очень веской причины поступить иначе. Вложите силы в тесты, в понятные модули и в автоматизацию деплоя — это пригодится при любом сценарии. Заведите правило, что модуль общается с другими только через публичный интерфейс, и следите за этим на ревью. Ведите список мест, которые реально болят: частые конфликты в репозитории, необходимость масштабировать только одну часть системы, разные требования к надёжности. Когда таких пунктов наберётся достаточно, решение о выделении сервиса примете уже осознанно, а не по веянию моды. И не бойтесь сделать шаг назад: превратить два слишком мелких сервиса обратно в один модуль — это не поражение, а зрелость.

Про выбор под свой масштаб я теперь объясняю коллегам через простую аналогию. Монолит — это одна дружная мастерская, где все видят работу друг друга и быстро договариваются, но с ростом людей становится шумно. Микросервисы — это сеть отдельных цехов с собственной логистикой: каждый свободен, но нужно вкладываться в транспорт, склады и диспетчерскую, иначе всё встанет. Модульный монолит — это та же мастерская, но с аккуратно разделёнными зонами и чёткими правилами передачи деталей между ними. Для большинства российских продуктовых команд среднего размера, с которыми я работал, третья схема оказывалась самой выгодной по соотношению скорости разработки и стоимости эксплуатации.

А теперь мне интересно ваше мнение, форумчане. Расскажите, с какой архитектуры вы начинали свой последний проект и что заставило вас её изменить или, наоборот, остаться на месте? Было бы здорово услышать истории и про удачные переезды, и про болезненные откаты — уверен, у каждого здесь найдётся свой ценный опыт, который поможет новичкам не наступить на те же грабли.
 
Назад
Вверх