Шина и монолит
Шина и монолит

Великий аргентинский писатель Хорхе Луис Борхес в одном из своих произведений попытался доказать, что вся мировая литература сводится к четырем базовым сюжетам: истории об осаде и защите обречённого города, истории о возвращении, истории о поиске и истории о жертвоприношении или самоубийстве бога. В комментарий к этому заявлению Виктор Пелевин в одном из своих романов написал: "А по-моему, сюжетов всего два. Первый – как человека убивают из-за денег. Второй – как человека приносят в жертву. А на самом деле оба сюжета можно даже объединить в один". Как бы то ни было, оставим спор о сюжетах литературоведам. В этом посте я хочу разобрать схожий тезис - все архитектуры разных видов программного обеспечения можно свести к двум базовым структурам - монолиту и шине.

Операционные системы

В операционных системах есть два типа ядер:

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

Микроядро предоставляет минимальный набор системных функций, а все модули, в том числе драйверы и файловая система, подключаются к нему и общаются друг с другом через сообщения по шине данных. Это даёт возможность заменять модули на лету - например, подгрузить драйвер без перекомпиляции и даже без перезапуска операционной системы. И ошибка в одном из модулей никак не затронет другие. Более того, можно выкинуть из операционки все ненужные модули, что сильно снизит её размер в байтах. Да и тестировать отдельные модули гораздо проще, чем огромный единый монолит. Недостаток же микроядерных ОС заключается в том, что за удобства приходится платить оверхедом по производительности и более низкой, чем у монолитных систем, скоростью работы.

Примеры ОС с монолитным ядром: Linux, MacOS, Windows. Знаменитый синий экран смерти в Windows возникает как раз из-за монолитности его ядра. Но даже в этих операционных системах используется похожая на микроядерную архитектура подгрузки внешних модулей, так что вернее было бы назвать их гибридными.

Примеры ОС с микроядром: учебный MINIX и операционная система реального времени QNX. Микроядерные системы часто используются в автомобилях, станках, самолетах, космических спутниках и кораблях и вообще везде, где важна стабильность, отказоустойчивость, маленький размер и возможность работать в реальном времени, то есть, иметь строго заданное время исполнения различных функций и фиксированное время отклика.

В 1992 году состоялся знаменитый спор создателя Linux Линуса Торвальдса и создателя MINIX Эндрю Таненбаума о преимуществах и недостатках монолитных ядер и микроядер.

Бекенд

При разработке бекенда тоже используется два подхода к построению его архитектуры:

  • Монолит

  • Микросервисы

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

В микросервисном подходе модули приложения разделены по разным сервисам - то есть по сути разным приложениям, которые могут запускаться на разных серверных машинах. Общаются друг с другом микросервисы либо вызовами по сети, либо с помощью шины событий (event bus). Эта архитектура более медленная из-за взаимодействия модулей друг с другом по сети, более сложная в разработке, ведь необходимо деплоить и оркестировать множество модулей. Но в то же время микросервисы гораздо легче скейлить. Кроме того использование event bus позволяет использовать такие подходы как CQRS и event sourcing.

Фронтенд

При разработке фронтенда тоже используется два подхода:

  • Монолитное приложение

  • Микрофронтенды

Всё по аналогии с монолитом и микросервисами на бекенде. Но на фронтенде шинная архитектура используется и в других местах.

Во-первых, вся интерактивность в браузере построена на отправке и прослушивании событий. В любом месте кода можно как отправить любой ивент через window.dispatchEvent, так и подписаться на него через window.addEventListener.

Во-вторых, многие системы управления состоянием вроде Redux тоже представляют собой шину событий, которые редуцируют поток событий в текущее состояние подобно тому, как на бекенде при использовании event sourcing поток ивентов превращается в materialized view в базе данных.

Многопоточность

При разработке многопоточных систем тоже используется два подхода:

  • Ручное управление (философски ближе к монолитному подходу)

  • Акторы/корутины (шина)

При ручном управлении возможно выжать большую производительность, но разработка и отладка системы с семафорами, локами, волатильными переменными и прочими хитрыми инструментами превращается в ад.

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

Факторио

На Хабре есть прекрасная серия статей про архитектуру разработки фабрики в игре Factorio:

Шина ресурсов в Factorio
Шина ресурсов в Factorio

В этих статьях автор рассказывает про то, как он строит фабрику в факторио: сначала с монолитной архитектурой, потом с микросервисной архитектурой без шины, а после с микросервисной архитектурой с шиной.

Заключение

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

P. S.: в моём телеграм‑канале я не пишу про архитектуру ПО, но пишу про философию, математику и буддизм.

Комментарии (9)


  1. SolidSnack
    10.09.2025 15:50

    Так быстро от архитектуры ОС до фронтенда я еще не прыгал...


    1. a-tk
      10.09.2025 15:50

      Что лишь подтверждает общее в этих решениях.


      1. SolidSnack
        10.09.2025 15:50

        Как минимум код, а если серьёзно - на сколько я понял, микросервесная архитектура (ядра) в MINIX, отличается от Linux, способом взаимодействия программ с железом и между собой, но миниксу не надо поднимать сервера чтобы запустить процесс, у всех уже ассоциация - микросервис значит gRPC (чтобы всем говорить что у нас как в гугл), если уж говорить про веб разработку, например SSR делает SEO оптимизацию лучше, поэтому лучше не выносить все в браузер на JS

        Ну и к слову, исторически, получается "монолит" победил ;)


        1. a-tk
          10.09.2025 15:50

          Монолит проще и надёжнее, и нет смысла делать мелкосервисы, если не доказана их необходимость.

          PS: проектирование любой системы с микросервисов очень напоминает разработку мелкой консольной утилитки на Java с написания фабрик фабрик.


  1. tkutru
    10.09.2025 15:50

    Да это просто извечный вопрос поиска "золотой середины". Сколько отдыхать, а сколько работать. Расти в знаниях вглубь или вширь. Насколько сильно изолированы должны быть транзакции в бд (надежность vs скорость). Компиляция vs интерпретация. Статическая vs динамическая типизация. Быстро-дешево-качественно - выбери два из трёх (CAP теорема Брюера туда же). Монолит vs микросервисы. И так далее.

    И как правило это не выбор между одним либо другим, а выбор точки, которая насколько-то ближе к одному либо к другому.


  1. aronsky
    10.09.2025 15:50

    Я про выход из АйТи вообще-то пришел читать…


    1. Doctor777
      10.09.2025 15:50

      Соглашусь - третий тезис из кликбейтного заголовка не раскрыт совсем...