В битве между Монолитом, Микросервисами и Модульным монолитом — кто будет проигравшим?
Кто будет проигравшим?
Обычно это дедлайн ⚰️💣
Если вам когда-нибудь хотелось вкинуть холивар на встречу — просто спросите, какая архитектура лучше: монолит, микросервисы или модульный монолит. Затем отойдите на безопасное расстояние. В этой статье я проведу сравнение этих подходов с точки зрения системного аналитика, который отбил все места граблями и превратил это в ритуал.

Монолит: когда все яйца в одной корзине
Монолитная архитектура — это классический подход к разработке программного обеспечения, при котором все компоненты системы упакованы в один большой исполняемый файл. Представьте себе, что вся ваша система — это огромный комок пластилина из разных цветов, в котором запутались все функции, сервисы и зависимости. «Работает — не трогай» — это не просто девиз, это способ сохранить свою психику в условиях абсолютной неопределенности монолитного кода.
Преимущества монолита (которые мы любим перечислять на собеседованиях):
- Простота разработки — весь код в одном месте, можно быстро найти любую функцию (если, конечно, вы носитель родоплеменного контекста)
- Легкость развертывания — просто скопировал файл и готово (если только ваш монолит не весит как фильм в HD)
- Отсутствие проблем с сетевыми вызовами — все функции вызываются напрямую (и падают тоже напрямую, без посредников)
- Единая транзакционная модель — ACID на всю систему/
Недостатки монолита (о которых мы обычно узнаем на третий год разработки):
- Сложность поддержки — через год даже автор кода не помнит, как это работает
- Масштабирование только целиком — нельзя увеличить мощность только для части системы
- Сложность внедрения изменений — одно изменение может сломать всю систему ( обычно в пятницу вечером)
- Технологическая жесткость — нельзя использовать разные технологии в разных частях системы (но зато все разработчики страдают одинаково)
Монолиты идеально подходят для стартапов и небольших проектов. «Мы быстро напишем MVP как монолит, а потом обязательно перепишем» — классическая легенда, которую все рассказывают на планировании первой версии. Спустя годы, эту фразу можно обнаружить только в архивных записях, о которых носитель контекста пытается не вспоминать, если еще не сменил проект.
Микросервисы: разделяй и… страдай?
Микросервисная архитектура — это подход, при котором система разбивается на множество небольших независимых сервисов, каждый из которых обслуживает одну конкретную функцию бизнеса. Это как если бы вы разделили дом на отдельные комнаты, а потом расставили их в разных частях города, соединив телефонными проводами. Эффективно? Возможно. Сложно? Определенно.
Преимущества микросервисов:
- Независимое масштабирование — каждый сервис масштабируется отдельно (и каждый ломается отдельно, что удобно для поиска виноватых)
- Технологическая гибкость — разные сервисы на разных технологиях ( зоопарк из технологий, что может пойти не так?)
- Более быстрая разработка — несколько команд могут работать параллельно (здоровья их Delivery Manager`у)
- Легкое внедрение изменений — изменение одного сервиса не влияет на остальные (пока не выясняется, что влияет, и еще как)
Недостатки микросервисов (о которых вспоминает ночной саппорт):
- Сложность инфраструктуры — нужно управлять десятками или сотнями сервисов
- Распределенные транзакции — согласованность данных превращается в отдельный вид искусства
- Сетевые задержки — каждый вызов между сервисами проходит по сети (и где-то там грустит пользователь, ожидая ответа)
- Сложность отладки — трассировка запроса через несколько сервисов похожа на путь по хлебным крошкам после дождика в четверг
«Давайте перейдем на микросервисы, как Netflix и Amazon!» — типичное предложение от разработчика, который прочитал статью в Medium, но никогда не поддерживал микросервисную архитектуру в промышленной эксплуатации. Следующая фраза обычно: «Сроки? Конечно, успеем к концу спринта!»
Модульный монолит: когда хочется и рыбку съесть, и на стул не сесть
Модульный монолит — это компромисс между монолитом и микросервисами. Представьте себе квартиру, где комнаты разделены стенами, но все еще находятся в одном здании. Каждый модуль имеет четкие границы и API, но все они упакованы в одно приложение и разделяют одни ресурсы.
Преимущества модульного монолита (которые звучат почти убедительно):
- Четкие границы между модулями — код организован в логические модули (которые, впрочем, всегда находят способ проникнуть друг в друга)
- Простота развертывания — всё еще один процесс, один артефакт (один большой баг)
- Возможность эволюционировать к микросервисам — при необходимости модули могут стать независимыми сервисами (в теории, на практике обычно это «мы потом сделаем»)
- Общие ресурсы — модули могут использовать общую базу данных и другие ресурсы
Недостатки модульного монолита (которые мы замечаем спустя год разработки):
- Всё еще монолит — масштабируется целиком (как зарплатные ожидания после года работы)
- Более сложная архитектура — нужно тщательно проектировать модули и их взаимодействие (а «тщательно» и «дедлайн» — понятия несовместимые)
- Требует дисциплины от разработчиков — нужно строго следовать архитектурным принципам
- Риск превращения в беспорядочный монолит — без должного контроля границы между модулями размываются (особенно после фразы «Мы стейкхолдерам обещали еще вчера»)
«Давайте сделаем модульный монолит, это лучшее из обоих миров!» — обычно предлагает технический лид после того, как пожил с микросервисами и вспомнил старые добрые времена монолитов. И это действительно может сработать, если у вас в команде есть архитектурный надзиратель с дубинкой для соблюдения границ между модулями.
Сравнительная таблица: выбери наименьшее зло
Критерий | Монолит | Микросервисы | Модульный монолит |
---|---|---|---|
Скорость разработки | Быстро в начале, потом «оно работает, не трогай» | Медленно в начале, потом «это другой сервис, не мое» | Умеренная, с периодическими криками «кто сломал границы модулей?!» |
Масштабируемость | Только целиком (как любовь к начальнику — либо есть, либо нет) | Отдельными сервисами (как диета по дням недели) | Только целиком (но с иллюзией контроля) |
Надежность | Падает всё сразу (особенно в пятницу вечером) | Падает по частям (и обычно когда вы в отпуске) | Всё еще падает всё сразу, но хотя бы понятно, какой модуль виноват |
Сложность инфраструктуры | Низкая (один сервер, одна молитва) | Высокая (Kubernetes кластер и шаманские бубны) | Средняя (один деплой, но с хитрой конфигурацией) |
Когда объяснять начальству | «Так всегда делали» | «Так делают в Google» | «Это золотая середина, поверьте по братски» |
Переиспользование кода | Легко (скопировал-вставил и забыл) | Сложно (создание отдельных библиотек для каждой функции) | Средне (общие модули, которые никто не документирует) |
Ключевые выводы для тех, кто дочитал до конца (или сразу прокрутил сюда):
Монолит
- Выбирайте, если: у вас маленький проект, ограниченные ресурсы, нужно быстрее выйти на рынок и проверить идею
- Не выбирайте, если: у вас большая команда разработчиков, которые любят писать в одном файле одновременно и выяснять, чей коммит важнее
- Девиз: «Работает? Не трогай! Хотя, погоди, оно и не работало никогда…»
Микросервисы
- Выбирайте, если: у вас большая система с разными уровнями нагрузки, много команд и вы уже подписали контракт с AWS на крупную сумму
- Не выбирайте, если: у вас нет выделенной DevOps команды и бюджета на мониторинг, или вам нравится спать по ночам
- Девиз: «500 микросервисов и все равно никто не знает, где баг»
Модульный монолит
- Выбирайте, если: вы хотите хорошую организацию кода без необходимости разворачивать армию контейнеров
- Не выбирайте, если: у вас нет архитектора-диктатора, который будет следить за границами между модулями
- Девиз: «Мы не делаем микросервисы, это слишком сложно! (Но на самом деле мы просто не знаем, как)»
И помните главное правило архитектора: какую бы архитектуру вы ни выбрали, через год вы всё равно будете жалеть о своем выборе.
Заключение
Выбирайте с улыбкой, живите здесь и сейчас. Потом разберетесь.
Выбор архитектуры — это всегда компромисс. Нет идеального решения, которое подойдет всем. Монолиты хороши для быстрого старта, микросервисы — для больших распределенных систем, а модульные монолиты — для тех, кто хочет организованный код без операционной сложности микросервисов.
На своем примере могу сказать: какую бы архитектуру вы ни выбрали, важнее всего последовательность и дисциплина в её реализации. И небольшая доза фатализма не помешает — все равно через пару лет вы будете всё переписывать под новые требования.
А если заказчик спросит, какую архитектуру лучше выбрать, всегда можно ответить классическим аналитическим «зависит от ваших потребностей» и провести трехчасовой воркшоп по выявлению этих самых потребностей. К концу воркшопа обычно уже никто не помнит, с чего началось обсуждение, и вы можете спокойно предложить любой вариант.
И помните: какой бы ни была архитектура вашей системы, в конечном итоге всё упирается в людей, которые её разрабатывают и поддерживают. Даже самая элегантная архитектура может превратиться в чудовище в неумелых руках. И наоборот, даже с монолитом можно жить счастливо, если ваша команда знает, что делает и умеет писать тесты.
PS: Автор данной статьи не несет ответственности за архитектурные решения, принятые под влиянием прочитанного материала.