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

Приложение, имеющее монолитную архитектуру, поставляется в виде единого компонента (например, одного исполняемого файла или в виде единого приложения на Rails или NodeJS).

Преимущества

  • Легко разрабатывать - хорошая поддержка со стороны средств разработки и IDE.
  • Легко разворачивать - достаточно выложить один исполняемый файл на сервер.
  • Легко масштабировать - можно запускать несколько экземпляров одного приложения за балансировщиком.

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

Недостатки

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

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

Приложение, имеющее микросервисную архитектуру, состоит из слабо-связанных взаимодействующих сервисов. Каждый сервис имеет следующие свойства:

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

Сервисы общаются между собой используя либо синхронные протоколы, такие как HTTP/REST, или асинхронные протоколы, такие как AMQP. Сервисы могут разрабатываться и обновляться независимо друг от друга. Каждый сервис имеет своё хранилище данных. Согласованность данных между сервисами поддерживается с применением паттерна Саги.

Преимущества

  • Ускоряет процессы CI/CD большого приложения:
    • Легче поддерживать - каждый сервис относительно маленький, поэтому в нём проще разобраться и изменять.
    • Проще тестировать - тесты прогоняются быстрее на маленьких сервисах.
    • Проще развёртывать - сервисы можно развёртывать независимо.
    • Можно независимо разрабатывать - сервисом может заниматься отдельная небольшая команда.
  • Небольшие сервисы:
    • Проще разобраться.
    • IDE работает быстро на небольшой кодовой базе,
    • Приложение запускается быстрее.
  • Улучшение стабильности - проблемы в одном сервисе не роняют всё приложение.
  • Проще менять технологии - при разработке нового или существующего сервиса можно выбрать новый стек технологий.

Недостатки

  • Необходимо решать проблемы построения распределённых систем, которых нет в монолитной архитектуре:
    • Нужно разработать (или подобрать готовый) механизм межсервисного взаимодействия.
    • Сложнее разрабатывать запросы, которые требуют взаимодействия нескольких сервисов, а также может потребоваться координация с другими командами.
    • Сложнее тестировать взаимодействие между сервисами.
    • Средства разработки заточены под монолитную арзитектуру.
  • Процесс развёртывания усложняется для всего приложения в целом.
  • Запросы между сервисами по сети дороже, чем вызов функции в рамках одного приложения.
  • Повышенное потребление оперативной памяти.

Источники: