Микросервисы глазами менеджера

Предисловие

Я — руководитель группы разработки, провожу технические собеседования в крупных компаниях. И с каждым разом всё чаще замечаю одну тревожную тенденцию. Я спрашиваю кандидата: «Зачем нужны микросервисы?» Он отвечает: «Для масштабирования». Я говорю: «Ок, а как бы ты масштабировал монолит?» Кандидат: «Ну... поставил бы несколько инстансов за балансировщиком». Я: «Отлично. Тогда зачем микросервисы?» Кандидат: «Ну... для отказоустойчивости». Я: «А graceful degradation в монолите можно сделать? Circuit breakers, fallback'и?» Кандидат: «Можно...» Я: «Тогда зачем микросервисы?» И тут кандидат зависает, потому что он не знает настоящего ответа. Он просто выучил набор слов или услышал их от кого-то, но в самой сути не разобрался.

В последнее время, если система - монолит, то она у всех вызывает отторжение, тим лид на собесах стыдиться сказать, что их система монолит, члены команды зачастую также считают это плохим подходом и считают, что если система монолит, то это legacy. В связи с этим я хочу рассказать, почему микросервисы - это не круто, а дорого и сложно.

1. Что такое микросервисы на самом деле?

Микросервисная архитектура (MSA) — это не про технику. Это **про команды**. Если у тебя 2 команды, работающих над одним монолитом, они будут конфликтовать. Если у тебя 10 команд — они будут убивать друг друга. MSA решает **организационную проблему**: как сделать так, чтобы команды могли разрабатывать и выкатывать фичи независимо друг от друга. **Это единственное обоснование выбора MSA.** Соответственно выбор MSA - это не выбор архитектуры из-за NFR, а выбор архитектуры для организации командной работы. Тим лид управляет двумя ресурсами - трудомощность и трудоемкость, аля velocity и capacity из scrum, и если обьем бэклога на систему возрастает, то нужно увеличивать и трудомощность, 1 тим лид не сможет эффективно управлять командой из 40 человек, здесь уже нужно несколько команд, поддеживающих одну и ту же информационную систему(ИС), тут то и нужно микросервисы. А когда в целом система состоит из 40 микросервисов, эту ИС поддерживает одна команда - то это просто бред.

2. Мифы, которые нужно развеять

Миф 1: Микросервисы нужны для более простого масштабирования и для отказоустойчивости

Горизонтальное масштабирование — это про **stateless**, если система хранит состояние, ее тоже можно масштабировать, но там надо думать, как это сделать. Если система не хранит состояние, ты ставишь 10 инстансов монолита за прокси(балансировщиком) — и все спокойно масштабируется.

Да, в MSA ты можешь масштабировать только самый нагруженный сервис отдельно. Но это требует дополнительной инфраструктуры, балансировки запросов между сервисами, а также доп издержки на observability для каждой системы.

**Альтернатива в монолите:** профилируешь, находишь узкое место, выносишь его в отдельный модуль, масштабируешь весь монолит или только этот модуль. Да, это сложнее. Но не настолько, чтобы переписывать всю систему на MSA.

А что касаемо отказоустойчивости, когда говорят про отказоустойчивость: обычно имеют в виду паттерны для отказоустойчивости, аля circuit breaker, bulkhead, rate limiting, fallback и т.д. В монолите все это тоже можно сделать, можно сделать graceful degradation, сделать graceful shutdown в монолите даже проще, чем в MSA. Да, если в монолите падение модуля заденет другой, если они используют общие ресурсы, но если правильно спроектировать монолит, то можно добиться почти той же отказоустойчивости, что и в MSA.

Миф 2: Микросервисы нужны для большой базы

В MSA объем бд не магическим образом уменьшается, за это есть плата в виде распределенной транзакции, и это уже сильно сложнее чем просто транзакции в монолите, т.к. ACID в MSA нельзя поддержать, то нужно что-то думать, например, Saga, 2PC и т.д. - а это сильно сложнее, чем обычная транзакция. Ды и впринципе оптимизация бд осуществляется другими способами: шардинг, репликация, партицирование и т.д. все это опять же можно сделать и с монолитом

Миф 3: Микросервисы нужны для независимых релизов

Вот тут мы потихоньку подходим к действительной причине выбора MSA. MSA позволяет катить фичимо независимо, но каждой команде нужен свой CI/CD, сервисы должны быть слабо связанными, поддерживать обратную совместимость, версионирование, а это уже крайне тяжело сделать, так как во многих компаниях куча разрабов просто фигачит брейкинг ченджи в каждом релизе, поэтому про независимый выкат говорить не приходится, командам нужно состыковать свои релизные циклы и по изменениям которые коснуться других команд договариваться, чтобы катиться в одно и то же время. В монолите кстати говоря можно тоже катиться независимо друг от друга, если соблюдены условия для MSA выше. Можно использовать паттерн SUFA, можно модули разбить на разные репозитории и организовать независимый выкат.

Миф 4: Микросервисы для стартапов имеют место быть, если высокие NFR

Стартапам категорически нельзя начинать с MSA. если ты стартап - то у тебя нет кучи команд, иначе вы будете много времени тратить на координацию, у тебя нет денег и времени на построение нормальной инфраструктуры, ты умрешь от распределенных транзакции и eventual consistency, ты не знаешь product market fit - ты будешь часто переписывать код, в MSA кода больше будешь больше переписывать.

3. Как правильно делать монолит

Да, если делать монолит плохо — он будет плохим. Но проблема не в монолите, а в **инженерной дисциплине**. ### Принципы хорошего монолита: 1. **Модульность.** Разбивай код на модули по бизнес-доменам (DDD), а не по слоям(слой инфры, слой бд). Каждый модуль — это независимая единица с чёткими границами. 2. **SUFA-паттерн (Self-Contained Functional Architecture).** Каждый функциональный компонент содержит всё необходимое: код, конфиги, миграции. Это позволяет легко выносить модуль в отдельный сервис, если когда-нибудь понадобится. 3. **Никаких God Object'ов.** Один класс, который знает всё и делает всё — это антипаттерн. Дели на маленькие классы с одной ответственностью. 4. **Чёткие границы между модулями.** Модули общаются через публичные API (не через shared-модели!). Это делает возможным будущее разделение на сервисы.

Когда монолит пора делить? Когда количество команд превышает **3–5**, и они начинают конфликтовать в коде, затягивать CI/CD, бояться релизов. Это сигнал, что пора либо делить на модули с независимыми релизами, либо выносить в MSA.

9. Итого

Правильный ответ про то, когда нужно MSA: «Микросервисы — это не про технику. Это про команды. Мы используем их, чтобы разные команды могли разрабатывать и выкатывать фичи независимо друг от друга. Всё остальное — масштабирование, отказоустойчивость, производительность — можно сделать и в монолите. Просто это сложнее или требует других подходов. MSA даёт более грубую гранулярность, но за это мы платим деньгами, инфраструктурой и сложностью разработки.» Если кандидат отвечает так — он понимает архитектуру. Если он начинает говорить про Kubernetes, Docker, и Service Mesh, но не про команды — он не понимает сути.

P.S. Для тех, кто всё ещё думает про MSA Если вы четко не можете провести границы в домене, разбить его на независимые модули(именно модули, не слои), то скорее всего ваши микросервисы станут "распределенным монолитом" независмых релизов у вас не будет, отказоустойчивости у вас не будет, будет сильная связанность и поддерживать такую систему будет сложнее.