Сайт использует сookies для хранения данных. Продолжая использовать сайт, вы даёте согласие на работу с этими файлами.

ОК
💻
Технологии
Опубликовано:
19.10.2026
•
Обновлено:
19.10.2026

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

Илья Новиков

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


Анатомия подходов: что скрывается под терминами

Классический монолит

Классический монолит представляет собой систему, в которой вся бизнес-логика скомпонована в единый исполняемый артефакт (deployable unit), исполняется в общем процессе операционной системы и, как правило, использует единую базу данных.

Главное свойство классического монолита — минимальная стоимость межкомпонентных вызовов (вызовы функций в памяти) и простота сквозных ACID-транзакций. Однако при отсутствии строгой архитектурной дисциплины монолит со временем рискует деградировать в сильно связанный код, где изменения в одном модуле непредсказуемо влияют на функциональность другого.

Модульный монолит (Modular Monolith)

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

  • функциональность разделена на логические модули в соответствии с ограниченными контекстами (Bounded Contexts);
  • взаимодействие между модулями происходит строго через публичные интерфейсы (API модуля) или внутреннюю шину событий в памяти;
  • модули не имеют прямого доступа к внутренним структурам данных и таблицам базы данных друг друга (логическое разделение схем или изоляция на уровне сущностей);
  • архитектурные правила и запреты нежелательных связей верифицируются на этапе сборки с помощью линтеров или тестов структуры кода.

Этот подход обеспечивает изоляцию компонентов без необходимости оплачивать накладные расходы распределенной инфраструктуры.

Микросервисная архитектура

Микросервисная архитектура — это распределенная система, состоящая из независимых автономных сервисов, каждый из которых:

  • решает узкую задачу вокруг бизнес-возможности (business capability);
  • владеет собственным изолированным хранилищем данных (паттерн Database-per-Service);
  • развертывается и масштабируется независимо от остальной системы;
  • взаимодействует с другими сервисами по сети через синхронные (gRPC, HTTP/REST) или асинхронные протоколы (брокеры сообщений).

Автономия сервисов приобретается ценой сетевых задержек, усложнения оркестрации и необходимости решать задачи распределенной согласованности данных.


Сравнение вариантов по ключевым осям принятия решений

Классический монолит    --> Единый артефакт, общая БД, внутрипроцессные вызовы
Модульный монолит       --> Единый артефакт, строгие границы доменов, изоляция данных
Микросервисы            --> Множество артефактов, БД на сервис, сетевое взаимодействие (RPC/Event-driven)

Границы домена и связанность (Coupling & Domain Boundaries)

Степень понимания предметной области — определяющий фактор при выборе архитектуры.

  • Классический монолит прощает неточности в границах домена на начальных этапах: рефакторинг кода и перенос логики внутри одного репозитория выполняются базовыми средствами среды разработки.
  • Модульный монолит требует осознанного выделения модулей, но позволяет скорректировать ошибочно проведенные границы без дорогостоящей миграции сетевых API и разделения баз данных.
  • Микросервисы требуют устойчивой доменной модели. Если границы проведены неверно, система превращается в «распределенный монолит»: любые изменения требуют одновременного развертывания нескольких сервисов, а сетевые вызовы между ними становятся избыточно частыми (chatty I/O).

Структура и масштаб инженерной команды (Закон Конвея)

Организационная структура напрямую отражается на архитектуре программной системы:

  • 1–3 команды (до 15–20 инженеров): Классический или модульный монолит обеспечивает максимальную скорость поставки (Time-to-Market). Команда работает в едином контексте без накладных расходов на согласование распределенных контрактов и версионирование внешних API.
  • Несколько параллельных стримов разработки: Модульный монолит позволяет закрепить ответственность за модулями (Code Ownership) за отдельными группами разработчиков в рамках одного репозитория.
  • Множество независимых продуктовых команд (от 30–50+ инженеров): Микросервисы становятся оправданными, когда координация единого релиза превращается в узкое место. Команды получают возможность независимо разрабатывать, тестировать и развертывать свои сервисы.

Профиль нагрузки и масштабирование (Scalability)

  • Монолит и модульный монолит масштабируются путем репликации всего приложения за балансировщиком нагрузки. Это практично и экономично, если профиль нагрузки распределен по системе относительно равномерно. Однако если одна ресурсоемкая операция требует специфического оборудования (например, GPU для вычислений или большой объем RAM), масштабировать придется весь монолит.
  • Микросервисы позволяют точечно выделять вычислительные мощности под узкие места системы. Платой за это выступают сетевые накладные расходы: каждый межсервисный вызов добавляет задержку на передачу данных по сети, сериализацию и десериализацию payload.

Эксплуатация, надежность и наблюдаемость (Operations & Observability)

Сложность поддержки распределенной системы возрастает нелинейно:

  • Монолитные системы: Локальное окружение запускается одной командой. Отладка выполняется стандартными инструментами IDE в едином процессе. Мониторинг сосредоточен вокруг сбора логов и метрик базового процесса и базы данных.
  • Микросервисы: Требуют зрелой платформенной инфраструктуры: Service Discovery, распределенной трассировки (Distributed Tracing), централизованного логирования, инструментов управления сетевыми сбоями (Circuit Breaker, Retries). Сбой сети между сервисами переходит в категорию штатных ситуаций, которые программный код обязан обрабатывать непрерывно.

Целостность данных и транзакционная модель

  • Монолитные архитектуры: Обеспечивают строгую согласованность данных (ACID) благодаря встроенным механизмам реляционных СУБД. Консистентность поддерживается на уровне единой транзакции.
  • Микросервисы: Принцип изоляции данных исключает простые транзакции между сервисами. Система опирается на модель согласованности в конечном счете (Eventual Consistency). Для реализации сквозных бизнес-транзакций требуется внедрение сложных паттернов: Saga (оркестрация или хореография), Transactional Outbox и идемпотентных обработчиков сообщений.

Сводная матрица критериев выбора

Параметр Классический монолит Модульный монолит Микросервисы
Сложность развертывания Низкая (1 артефакт) Низкая (1 артефакт) Высокая (множество артефактов)
Изоляция сбоев Низкая (сбой процесса затрагивает всю систему) Средняя (внутрипроцессная изоляция ошибок) Высокая (деградация локализована в рамках сервиса)
Сетевые накладные расходы Отсутствуют (вызовы в памяти) Отсутствуют (вызовы в памяти) Заметные (сетевой I/O, сериализация)
Сложность транзакций Низкая (локальный ACID) Низкая/Средняя (ACID или внутренние события) Высокая (Eventual Consistency, Saga)
Размер команды 1–3 команды До 5–8 команд при четких зонах ответственности Неограниченно при высокой автономии команд
Цена архитектурной ошибки Низкая (быстрый рефакторинг) Средняя (перенос модулей в коде) Высокая (миграция распределенных БД и API)
Требования к платформе/DevOps Базовые Базовые / Средние Высокие (K8s, трассировка, Service Mesh)

Дерево решений: пошаговый алгоритм выбора

Чтобы определить подходящую архитектуру, последовательно сопоставьте параметры проекта:

[Старт: Проектирование архитектуры]
       │
       ▼
1. Границы предметной области стабильны и четко формализованы?
       ├─► [НЕТ] ──► МОДУЛЬНЫЙ МОНОЛИТ (сохраняет гибкость для рефакторинга)
       │
       ▼ [ДА]
2. Над проектом работает более 4–5 независимых инженерных команд?
       ├─► [НЕТ] ──► МОДУЛЬНЫЙ МОНОЛИТ или КЛАССИЧЕСКИЙ МОНОЛИТ
       │
       ▼ [ДА]
3. Есть ли выраженная асимметрия нагрузки или необходимость в изолированном деплое узлов?
       ├─► [НЕТ] ──► МОДУЛЬНЫЙ МОНОЛИТ с разделением зон ответственности
       │
       ▼ [ДА]
4. В организации развернута зрелая DevOps-платформа (трассировка, CI/CD, оркестрация)?
       ├─► [НЕТ] ──► МОДУЛЬНЫЙ МОНОЛИТ (приоритет — развитие инфраструктуры)
       │
       ▼ [ДА]
ИТОГ: МИКРОСЕРВИСНАЯ АРХИТЕКТУРА
  1. Определенность домена: Если бизнес-модель проходит валидацию или часто меняется (MVP, ранние стадии продукта) — распределенная архитектура создает избыточное трение.
  2. Размер штата: При работе до 20–30 инженеров затраты на поддержку межсервисной инфраструктуры перекрывают выгоду от раздельного развертывания.
  3. Асимметрия нагрузки: Микросервисы дают результат, когда отдельным компонентам требуются принципиально разные вычислительные профили, жестко изолированные SLA или независимые релизные циклы.
  4. Инфраструктурная зрелость: Без автоматизированного тестирования, сквозного мониторинга и отлаженных процессов поставки переход к микросервисам приводит к потере контроля над системой.

Фиксация архитектурного выбора: шаблон записи ADR

Архитектурные решения рекомендуется документировать с помощью Architecture Decision Record (ADR) — лаконичного документа, фиксирующего контекст, принятые решения и компромиссы непосредственно в репозитории проекта.

Пример заполненного ADR

# ADR-001: Выбор базовой архитектуры платежного шлюза

## Статус
Принято (Accepted)

## Контекст
Проектируется новая система обработки платежей и управления счетами клиентов.
Вводные данные:
* Состав команды: 2 инженерные группы (всего 10 человек).
* Ожидаемая нагрузка: до 400 RPS в пиковые периоды, высокий процент транзакций записи.
* Доменная модель продолжает уточняться продуктовыми аналитиками.
* Выделенной платформенной команды нет, поддержка инфраструктуры лежит на продуктовых инженерах.

## Рассмотренные варианты
1. Микросервисная архитектура (сервисы платежей, счетов, уведомлений, аналитики).
2. Классический монолит.
3. Модульный монолит с изолированными доменными контекстами.

## Решение
Выбрать архитектуру **Модульного монолита**.
Кодовая база организуется в рамках одного репозитория с разделением на модули `Payment`, `Billing`, `Notifications`. Связи между модулями реализуются исключительно через публичные интерфейсы и внутренние события в памяти. Прямой доступ к таблицам чужих модулей запрещен правилами статического анализа.

## Последствия
### Положительные:
* Сохранение транзакционной целостности (ACID) без усложнения распределенными протоколами.
* Отсутствие сетевых задержек между компонентами.
* Простая и воспроизводимая локальная среда разработки.
* Низкая стоимость реорганизации доменных границ при изменении требований.

### Риски и ограничения:
* Общий runtime: аварийный сбой процесса останавливает все модули.
* Требуется постоянный автоматизированный контроль за архитектурными зависимостями в кодовой базе.

Часто задаваемые вопросы (FAQ)

Можно ли начать с монолита и затем перейти на микросервисы?

Да, если изначально проектировать систему как модульный монолит. Ключевые условия для последующего выделения сервисов: отсутствие прямых зависимостей в обход публичных интерфейсов, отказ от перекрестных внешних ключей (Foreign Keys) между контекстами в базе данных и асинхронный обмен сообщениями между модулями.

Когда микросервисы становятся объективно необходимыми?

Микросервисы незаменимы, когда масштаб организации превышает порог эффективной координации в общем релизном цикле (десятки продуктовых команд), либо когда отдельные узлы системы имеют несовместимые требования к ресурсам, контурам безопасности (например, зона соответствия PCI DSS) или частоте релизов.

В чем ключевое отличие модульного монолита от слабоструктурированного монолита?

В жестком контроле внутренних архитектурных границ. В модульном монолите каждый компонент инкапсулирует свою внутреннюю логику и схемы данных. Попытки обратиться к приватным классам или напрямую выполнить SQL-запрос к таблицам другого модуля блокируются линтерами и тестами архитектуры еще на этапе сборки.

Как определить, что в проекте получился «распределенный монолит»?

Основные признаки распределенного монолита:

  • сервисы невозможно обновить независимо (для релиза одного сервиса требуется синхронный деплой остальных);
  • правка модели данных в одном сервисе вызывает каскадные изменения в соседних сервисах;
  • несколько сервисов обращаются к одной и той же базе данных без разделения прав и схем;
  • сбой одного второстепенного сервиса приводит к полному отказу всей системы.

Уступает ли модульный монолит микросервисам по производительности?

В типовых сценариях модульный монолит демонстрирует меньшие задержки (latency), поскольку обмен данными происходит в оперативной памяти без сетевого стека, сериализации JSON/Protobuf и накладных расходов TLS. Микросервисы получают преимущество только тогда, когда конкретную изолированную операцию требуется масштабировать на десятки специализированных серверов отдельно от остального кода.


Вывод

Архитектура системы — это прикладной инструмент достижения бизнес-целей и обеспечения продуктивности инженерных команд, а не показатель технологической зрелости:

  1. Классический монолит и модульный монолит остаются практичным и устойчивым выбором для большинства проектов, небольших и средних команд, а также для систем с развивающейся структурой домена.
  2. Модульный монолит сочетает дисциплину изолированных доменов и простоту эксплуатации единого артефакта.
  3. Микросервисы решают задачи организационной независимости масштабных команд и избирательного масштабирования, но требуют существенных затрат на платформенную инфраструктуру, надежность сети и согласованность данных.

Выбирайте архитектуру исходя из реальных ограничений команды и требований к системе, обязательно фиксируя контекст и последствия в архитектурных записях (ADR).

Источники

Это авторская статья, основанная на личном опыте и субъективном взгляде автора. Заметили ошибку или битую ссылку? Сообщите нам: info@codesrc.ru - мы оперативно исправим. Спасибо, что помогаете делать блог лучше.
Следите за нами в соцсетях:

Читайте также