«Микросервисы» давно стали синонимом «правильной архитектуры», и команды дробят систему на сервисы ещё до того, как у них появляются проблемы, которые это решает. А потом тонут в распределённой сложности. Но дело в том, что и монолит, и микросервисы - инструменты со своими задачами, и выбор зависит от контекста, а не от моды. Эта статья разбирает, когда что выбирать, без догм в обе стороны.
Коротко:
- Микросервисы решают проблемы масштаба команды и независимого деплоя, а не «делают код лучше».
- Для большинства новых продуктов правильный старт - хорошо устроенный монолит.
- Микросервисы добавляют распределённую сложность: сеть, данные, наблюдаемость.
- Решает не размер кода, а число команд, нагрузка и реальные точки боли.
Что такое монолит и микросервисы
Монолит - единое приложение, где весь код деплоится как одно целое. Модули общаются вызовами функций внутри процесса, у системы одна база. Это не ругательство: монолит может быть отлично структурированным (модульный монолит).
Микросервисы - система разбита на независимые сервисы, каждый со своей ответственностью, своим деплоем и часто своей базой. Сервисы общаются по сети (HTTP/gRPC, очереди).
Ключевая разница не в «современности», а в границах: монолит развёртывается и масштабируется целиком, микросервисы - по частям и независимо.
Что на самом деле дают микросервисы
Микросервисы решают конкретный набор проблем:
- Независимый деплой. Команды релизят свои сервисы, не координируя один большой релиз. Критично, когда команд много.
- Независимое масштабирование. Можно масштабировать только нагруженный сервис, а не всё приложение.
- Изоляция отказов (при правильном дизайне) - падение одного сервиса не обязательно роняет всё.
- Технологическая свобода - разные сервисы на разных стеках.
- Организационный масштаб - много команд работают параллельно, не толкаясь в одном репозитории и релизе.
Главное слово здесь - масштаб: команд, нагрузки, организации. Микросервисы - это в первую очередь решение организационной, а не технической проблемы.
Цена микросервисов
За перечисленные выше выгоды платят распределённой сложностью:
- Сеть везде. Вызовы между сервисами могут падать, тормозить, требовать ретраев и таймаутов.
- Данные. Нет одной транзакции на всё - согласованность между сервисами становится сложной (саги, eventual consistency).
- Наблюдаемость. Чтобы понять, что произошло, нужен распределённый трейсинг, централизованные логи, мониторинг множества сервисов.
- Эксплуатация. Много деплоев, CI/CD, инфраструктура, версионирование API.
- Локальная разработка. Поднять десяток сервисов на ноутбуке - отдельная боль.
Для маленькой команды эта цена убивает скорость, которую якобы должна была дать «правильная архитектура».
Когда выбирать монолит
- Новый продукт, MVP, неустоявшиеся требования - вы ещё не знаете правильных границ.
- Небольшая команда (одна-две) - координация релизов не проблема.
- Нагрузка умеренная и не требует независимого масштабирования.
- Скорость важнее организационной гибкости.
Для большинства стартапов и новых продуктов правильный старт - модульный монолит: чистые внутренние границы, но один деплой. Когда (и если) появится реальная боль, отдельные модули можно вынести в сервисы.