Когда начинаете новый проект, один из первых вопросов — как разделить систему. Запустить всё одним приложением или сразу разбить на независимые сервисы? Ответ сильно зависит от команды, сроков и объёма задачи.
В этой статье разберём три варианта: слойный монолит, модульный монолит и микросервисы. Для каждого — когда он уместен, в чём его слабые места и как понять, что пора меняться.
Слойный монолит: один процесс, один деплой
Самый простой вариант. Всё приложение — один процесс: в нём и API, и бизнес-логика, и работа с базой данных. Деплоится одним файлом, отлаживается в одном месте.
Такой подход хорошо работает, когда:
- Нагрузка небольшая и предсказуемая (до 100–300 запросов в секунду).
- Команда маленькая — 1–3 разработчика.
- Нужно запустить продукт быстро.
- Домен узкий: сервис уведомлений, простой каталог товаров, прототип.
Что даёт: быстрая разработка, простая отладка, транзакции «из коробки», минимум инфраструктуры.
Где подведёт: когда кодовая база разрастается без чётких границ, разные части системы начинают мешать друг другу. Изменение в одном месте неожиданно ломает другое. Это называют «большой комок грязи» (Big Ball of Mud) — и это главный риск монолита без дисциплины.
Сигналы, что пора что-то менять:
- Разные части системы меняются с разной скоростью, а релизы всё равно нужно согласовывать.
- Команда выросла до 2+ независимых групп.
- Кодовая база перевалила за 50 000 строк и разобраться в ней становится сложно.
Модульный монолит: границы внутри одного приложения
Промежуточный вариант между монолитом и микросервисами. Физически это всё ещё один процесс и один деплой — но внутри чётко выделены модули с отдельными зонами ответственности. Каждый модуль работает со своей частью данных и общается с другими через события или явные интерфейсы, а не через прямые вызовы чужого кода.
Хорошо подходит, когда:
- Продукт потенциально большой, но нужен быстрый старт.
- Команда 5–7 человек, ожидается рост.
- Хочется сохранить возможность позже разбить на сервисы без переписывания всего с нуля.
Что даёт: нет сетевых задержек (всё в одном процессе), транзакции проще, чем в микросервисах, а структура уже готова к росту.
Где подведёт: границы между модулями легко нарушить — особенно когда торопятся. Чужая модель начинает просачиваться к соседу через «shared»-классы. Всё это надо отслеживать на ревью вручную. Ещё одна проблема: большой монолит тяжелее в IDE и при сборке.
Сигналы к разбивке на сервисы:
- Конкретный модуль стал узким местом по нагрузке и его нужно масштабировать отдельно.
- Команды разошлись и хотят деплоить независимо.
- Нужно отдать отдельный модуль сторонней команде.
- Кодовая база перевалила за 200 000 строк, команд стало три и больше.
Микросервисы: независимые сервисы с отдельными базами
Каждый сервис — отдельный процесс со своей базой данных. Сервисы общаются через HTTP или очередь сообщений. Деплоятся, масштабируются и падают независимо друг от друга.
Оправдано, когда:
- Проект крупный, сроки не поджимают, есть сильная команда и выстроенный DevOps.
- Разные части системы развиваются с разными требованиями к нагрузке и надёжности.
- Работают несколько независимых команд.
- Нагрузка высокая и неравномерная — одни сервисы нужно масштабировать, другие нет.
Что даёт: независимые релизы и масштабирование, изоляция сбоев (упавший сервис не роняет всё), разные технологии в разных сервисах.
Где подведёт: сетевые задержки, распределённые транзакции через Saga, сложная трассировка запросов, высокие требования к инфраструктуре (gateway, контрактные тесты, наблюдаемость). Это самый дорогой вариант по затратам на разработку и поддержку.
Когда точно не стоит:
- Маленькая команда или нет опыта с такой архитектурой.
- Домен ещё не стабилизировался — границы сервисов придётся постоянно переделывать.
- Срок запуска «вчера».
Подробнее о том, что нужно выстроить вокруг микросервисов: структурные паттерны и распределённые паттерны.
Как выбрать: простой чек-лист
За каждое «Да» — один балл:
| Вопрос | Да |
|---|---|
| Сроки не поджимают? | ☐ |
| Нагрузка высокая (>250 RPS) или пики критичны? | ☐ |
| Доменов пять и больше, они меняются независимо? | ☐ |
| Нужны независимые релизы у разных команд? | ☐ |
| Жёсткие требования к доступности (SLA 99.95%+ или p95 < 100 мс)? | ☐ |
| Система будет жить и развиваться несколько лет? | ☐ |
Итого:
- 0–1 балл → слойный монолит
- 2–3 балла → модульный монолит
- 4–6 баллов → микросервисы
Главное правило
Не выбирайте микросервисы потому что «так делают все крупные компании». Крупные компании пришли к этому после того, как монолит перестал справляться. Для маленькой команды с ранним продуктом монолит — это разумный выбор, а не компромисс.
Если домен вырастет, всегда можно мигрировать через паттерн Strangler Fig: постепенно вырезать части монолита в отдельные сервисы, не останавливая систему.
Коротко
- Слойный монолит — простой старт, минимум инфраструктуры; хорошо для маленьких команд и узкого домена.
- Модульный монолит — границы внутри одного приложения; позволяет расти и потом безболезненно разбиться на сервисы.
- Микросервисы — независимые процессы и базы; оправданы при высокой нагрузке, нескольких командах и зрелой инфраструктуре.
- Главный риск монолита — размытые границы (Big Ball of Mud). Главный риск микросервисов — сложность, которую команда не готова нести.
- Не выбирайте архитектуру под будущий рост, которого может не быть. Начинайте с простого и мигрируйте, когда монолит начнёт мешать.
Что почитать дальше
- Структурные паттерны микросервисов — обвязка, без которой микросервисы не живут.
- Распределённые паттерны — Saga, Outbox, идемпотентность.
- Паттерны отказоустойчивости — Retry, Circuit Breaker, Bulkhead.
- DDD: стратегические паттерны — Bounded Context как основа модульного разделения.