Главная › Блог › Монолит или микросервисы: что отвечать на собеседовании

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

Что на самом деле спрашивают

Вопрос «монолит или микросервисы» на собеседовании редко про архитектурную моду. Интервьюер проверяет, умеешь ли ты думать trade-off'ами: понимаешь ли, что любое архитектурное решение меняет одну проблему на другую, а не устраняет проблемы вообще. Плохой ответ — «микросервисы масштабируются лучше». Хороший ответ объясняет, какую именно боль решает декомпозиция и какую цену за это платишь.

Монолит: не ругательство, а стартовая точка

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

  • Один JVM-процесс — проще дебажить, профилировать, трассировать стек целиком.
  • Транзакции ACID из коробки — не нужен saga-паттерн для согласованности данных.
  • Деплой — одна операция. Нет проблемы совместимости версий сервисов.
  • Latency внутри процесса — вызов метода, а не сетевой round-trip.

Главная проблема монолита — не производительность, а organizational scaling. Когда над кодовой базой работают 50+ инженеров, растут конфликты в merge, время сборки, время деплоя, и самое болезненное — связанность модулей через общие таблицы и shared state, которая со временем превращается в big ball of mud.

Микросервисы: цена за независимость

Микросервисная архитектура решает организационную проблему: позволяет командам деплоить независимо, на разных стеках, с разным циклом релизов. Но это не бесплатно.

  • Распределённые транзакции — приходится жить с eventual consistency, применять saga или outbox pattern.
  • Сетевые вызовы — задержки, таймауты, retry-логика, circuit breaker.
  • Наблюдаемость — без distributed tracing (Zipkin, Jaeger) дебаг превращается в археологию по логам пяти сервисов.
  • Инфраструктурная сложность — service discovery, API gateway, конфигурация, деплой пайплайны на каждый сервис.
  • Тестирование — интеграционные тесты между сервисами дороже и хрупче.
Монолит — это открытая студия-квартира: все удобства рядом, но если делаешь ремонт, временно страдает вся квартира. Микросервисы — это отдельные квартиры с общим двором: ремонт в одной не трогает соседей, но теперь нужны лифты, домофоны и управляющая компания — то есть инфраструктура, которой в студии не требовалось.

Когда что выбирать

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

Практичный путь, который хорошо звучит на собеседовании: начинать с модульного монолита с чёткими границами (bounded context из DDD), и выделять сервисы только тогда, когда появляется реальная причина — отдельное масштабирование нагрузки, разный lifecycle релизов, разная команда-владелец. Это называют monolith-first подходом.

Частая ошибка — резать на микросервисы по техническим слоям (отдельно «сервис для контроллеров», отдельно «сервис для репозиториев»). Это distributed monolith: получаешь всю сложность сети, но без независимости деплоя, потому что сервисы всё равно надо релизить синхронно. Границы нужно проводить по бизнес-доменам, а не по архитектурным слоям.

Что проверяют на самом деле

Интервьюер хочет услышать осознание конкретных trade-off'ов, а не лозунг. Хороший ответ выглядит так: «Монолит проще в консистентности данных и дебаге, но плохо масштабируется организационно при росте команды. Микросервисы решают эту организационную проблему, но добавляют distributed systems сложность — eventual consistency, network partitions, наблюдаемость. Выбор зависит от размера команды, требований к consistency и зрелости DevOps-инфраструктуры, а не от модности технологии».

Отдельно часто спрашивают про миграцию: как резать монолит на сервисы без Big Bang-переписывания. Правильный ответ — паттерн Strangler Fig: новая функциональность выносится в отдельные сервисы, старый код постепенно обрастает прокси-слоем и выводится из эксплуатации по частям, а не переписывается целиком с риском сломать всё сразу.

Какую проблему решают микросервисы, если не производительность?
Организационное масштабирование: независимый деплой разных команд, разные стеки и циклы релизов. Производительность сама по себе от распределения часто только ухудшается из-за сетевых задержек.
Как понять, что пора резать монолит на сервисы?
Когда появляется конкретная организационная или нагрузочная причина: команды блокируют друг друга в общем релизном цикле, или один модуль требует отдельного масштабирования под нагрузку. Резать «на будущее» без этой причины — преждевременная сложность.

Ещё разборы