Node.js: application & deployment architecture overview

Архитектуры

I. Микросервисы

Концепция: архитектурный стиль микросервисов — это подход, при котором единое приложение строится как набор небольших сервисов, каждый из которых работает в собственном процессе и коммуницирует с остальными используя легковесные механизмы, как правило HTTP. Эти сервисы построены вокруг бизнес-потребностей и развертываются независимо с использованием полностью автоматизированной среды. Существует абсолютный минимум централизованного управления этими сервисами. Сами по себе эти сервисы могут быть написаны на разных языках и использовать разные технологии хранения данных.

Решаемая проблема:

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

  • даже небольшие изменения отнимают много времени из-за необходимости кросс-командного взаимодействия. Это приводит к тому, что команды размещают любую логику на тех слоях, к которым имеют доступ. Закон Конвея (Conway's Law) в действии. Крупные монолитные приложения тоже могут быть разбиты на модули вокруг бизнес потребностей, хотя обычно этого не происходит. Основная проблема здесь в том, что такие приложения имеют тенденцию к организации вокруг слишком большого количества контекстов. Если монолит охватывает множество контекстов, отдельным членам команд становится слишком сложно работать с ними из-за их большого размера. Кроме того, соблюдение модульных границ в монолитном приложении требует существенной дисциплины. Явно очерченные границы компонент микросервисов упрощает поддержку этих границ.

  • В монолитном приложении компоненты работают в одном процессе и коммуницируют между собой через вызов методов. Наибольшая проблема в смене монолита на микросервисы лежит в изменении шаблона коммуникации. Наивное портирование один к одному приводит к «болтливым» коммуникациям, которые работают не слишком хорошо. Вместо этого вы должны уменьшить количество коммуникаций между модулями.

Бенефиты:

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

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

  • Другое следствие использования сервисов как компонент — более явный интерфейс между ними. Большинство языков программирования не имеют хорошего механизма для объявления Published Interface. Часто только документация и дисциплина предотвращают нарушение инкапсуляции компонентов. Сервисы позволяют избежать этого через использование явного механизма удаленных вызовов.

  • На самом деле сервис может содержать множество процессов, которые всегда будут разрабатываться и развертываться совместно.

Цена:

  • Удаленные вызовы работают медленнее, чем вызовы в рамках процесса, и поэтому API должен быть менее детализированным (coarser-grained), что часто приводит к неудобству в использовании. Если вам нужно изменить набор ответственностей между компонентами, сделать это сложнее из-за того, что вам нужно пересекать границы процессов.
  • Как контролировать следование архитектуре (ключевые индикаторы):

  • Разбиение через сервисы - архитектура микросервисов использует библиотеки, но их основной способ разбиения приложения — путем деления его на сервисы. Сервисы — это компоненты, выполняемые в отдельном процессе и коммуницирующие между собой через веб-запросы или remote procedure call (RPS).

  • Организация вокруг потребностей бизнеса - Микросервисный подход к разбиению подразумевает раазбиение на сервисы в соответствии с потребностями бизнеса. Такие сервисы включают в себя полный набор технологий, необходимых для этой бизнес-потребности, в том числе пользовательский интерфейс, хранилице данных и любые внешние взаимодействия. Это приводит к формированию кросс-функциональных команд, имеющих полный набор необходимых навыков: user-experience, базы данных и project management.

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

  • Умные приемники и глупые каналы передачи данных (Smart endpoints and dumb pipes) - Комьюнити микросервисов предпочитает альтернативный подход: умные приемники сообщений и глупые каналы передачи. Приложения, построенные с использованием микросервисной архитектуры, стремятся быть настолько незавимыми (decoupled) и сфокусировнными (cohesive), насколько возможно: они содержат собственную доменную логику и выступают больше в качестве фильтров в классическом Unix-овом смысле — получают запросы, применяют логику и отправляют ответ. Вместо сложных протоколов, таких как WS-* или BPEL, они используют простые REST-овые протоколы.
    Два наиболее часто используемых протокола — это HTTP запросы через API ресурса и легковесный месседжинг. Лучшее выражение первому дал Ian Robinson: «Be of the web, not behind the web». Второй часто используемый инструмент коммуникации — легковесная шина сообщений. Такая инфраструктура как правило не содержит доменной логики — простые реализации типа RabbitMQ или ZeroMQ не делают ничего кроме предоставления асинхронной фабрики. Логика при этом существует на концах этой шины — в сервисах, которые отправляют и принимают сообщения.

  • Децентрализованное управление -

Как реализовать (сравнение с MBC / MAS), что сделать, что бы она применилась в проекте:

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

results matching ""

    No results matching ""