Перейти к содержанию

Монолит

Монолит - один deployable unit: весь код приложения в одном процессе, один артефакт, один деплой. Это ответ на вопрос топологии «сколько исполняемых единиц». Как код устроен внутри (ком без границ, слои, модули), решается в срезе Code (см. Layered Architecture и Modular Monolith).

  • изменил один компонент - редеплоишь весь артефакт
  • с контейнерами ладит плохо: очень жирному монолиту нужен либо очень жирный контейнер, либо декомпозиция, а это уже сервисы (SOA или микросервисы)
  • тяжёлая Java долго стартует, поэтому быстро и эластично добавлять копии под нагрузку не получается

Как масштабируется

Монолит скейлится копиями всего процесса за балансировщиком. В каждой копии весь код, все копии ходят в одну БД.

               +-----------------+
  клиенты ---> |  load balancer  |
               +-----------------+
                 |       |       |
                 v       v       v
           +--------+ +--------+ +--------+
           | копия 1| | копия 2| | копия 3|   один и тот же артефакт,
           +--------+ +--------+ +--------+   весь код в каждом процессе
                 \       |       /
                  v      v      v
                +-----------------+
                |     одна БД     |
                +-----------------+

Модули по отдельности не скейлятся. Узкое место в одном модуле - реплицируешь весь процесс, даже если остальной код в копиях простаивает.


Плюсы и минусы

Плюсы:

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

Минусы:

  • модули по отдельности не скейлятся, масштабируешь весь процесс целиком
  • общий runtime: память, GC, один упавший поток роняют всё приложение
  • общий релизный поезд: все модули едут одним деплоем, командам не порелизиться независимо

Модульный монолит

Тот же один deployable unit, но код внутри нарезан на модули с принудительными границами и своими данными. Топологически это обычный монолит, разница в коде (см. Modular Monolith).

Для топологии он важен как стратегия движения по оси:

  • Швы готовы заранее. Модуль, который действительно перерос процесс, выносят в сервис по готовому контракту, а не распутывают клубок.
  • Дефолт и часто конечная точка. Новый проект начинают с модульного монолита, микросервисы выделяют из готовых модулей потом и только если припрёт (MonolithFirst, Фаулер, 2015). Многие на нём и остаются, это не пересадочная станция.
  • Обратный ход. Распределённый монолит схлопывают назад в модульный: один деплой, строгие границы внутри (см. Distributed Monolith).