История микросервисов

«История микросервисов» – это краткий пересказ статьи «Microservices: The Evolution and Extinction of Web Services?» за авторством Luciano Baresi и Martin Garriga с моими дополнениями (курсивом).

Еще 20 лет назад SOA и Web Services были на пике популярности. Это был самый настоящий хайп. Особенность хайпа в том, что его применяют ради хайпа, а не для пользы дела, в массе своей даже не разобравшись в сути явления или технологии. Такое положение дел привело к тому, что количество определений и трактовок SOA и Web Services было примерно равно количеству внедрений 🙂 Это, в свою очередь, приводило к тому, что проблема подгонялась под решение. Сегодня то же самое происходит с микросервисами. Авторы статьи исследуют эволюционный путь от SOA к микросервисам на основе анализа литературы, как академической, так и научно-популярной.

Подгонка проблемы под решение выглядит примерно так: «мы решили распилить монолит на микросервисы, как обосновать это бизнесу?». Здесь «решение» уже выбрано, осталось найти под него проблему, а если проблем нет, то создатьпридумать её 🙂

Введение

Основная мысль заключается в том, что при широком внедрении SOA появились и новые стандарты: WSDL, BPEL, целью которых было убрать барьеры между системами в гетерогенной среде с целью снижения сложности решения задач интеграции. На практике такие решения оказались несостоятельными, главным образом из-за невозможности (by design) своевременно реагировать на постоянно меняющиеся бизнес-требования. (Здесь авторы не раскрывают мысль, но мы раскроем в последующих статьях)

Hype-цикл Гартнера
Hype-цикл Гартнера

Сегодня то же с микросервисами. Авторы акцентируют внимание, что определение микросервисов как «SOA done right» не вполне корректно, потому что в микросервисах фокус смещается с reuse и composition на independence, replaceability и autonomy. В таком случае сервисы становятся микро с точки зрения их вклада в приложение, а не по количеству строк кода.

Авторы определяют следующие, определяющие микросервисы, свойства:

  • Независимо понимаемые
  • Независимо реализуемые
  • Независимо развертываемые
  • Возможность одновременного сосуществование нескольких версий одного сервиса
  • При необходимости –  изменение топологии в режиме реального времени
  • Отдельный микросервис может быть изменен без влияния на работу других микросервисов

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

Микросервисы сталкиваются с рядом нетривиальных проблем проектирования, присущих любой распределенной системе:

  • Управление целостностью и согласованноситью данных
  • Спецификация интерфейсов и совместимость версий
  • Безопасность приложений и инфраструктуры

Рамках статьи авторы преследуют три цели:

  • Продемонстрировать эволюционный взгляд на движение от SOA к микросервисам
  • Обсудить текущие проблемы с микросервисами

Веб-сервисы тогда и сейчас

SOA(P) Services

SOA появилась как парадигма распределенных вычислений, работы электронного бизнеса и корпоративной интеграции.

Выгоды SOA

  • Динамичность (деление нагрузки по нескольким инстансам сервиса)
  • Повторное использование (одни и те же сервисы могут повторно использоваться разными системами)
  • Модульность (сложные сервисы состоят из более простых)
  • Распределенная разработка (параллельная разработка  сервисов по согласованным интерфейсам)
  • Интеграция гетерогенных и легаси систем используя стандартные протоколы (SOAP)

Отдельно авторы выделяют использование стандартных языков (BPEL) для оркестрации сервисов в сложные композиции.

Introduction to Oracle BPEL Process Manager
Oracle BPEL Process Manager

Далее авторы описывают причины частых провалов SOA:

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

Авторы дают отсылку к материалу «Managing Complexity of Information Systems — 2012 — Lemberger — Why Has SOA Failed So Often» и чтобы раскрыт тему глубже, приведу достаточно объемную цитату из этой статьи:

Many companies did things in the wrong order. Rather than building a robust and scalable architecture for their stable, core processes, they tried to achieve flexibility prematurely. In the most extreme cases, this led to the so-called alignment trap, namely the IT department spending most of their energy and money on maintaining an architecture that never had the time to become mature because of premature attempts to align IT with ever- changing business requirements (see section 3.3.3). It should be emphasized that an SOA architecture, if useful at all, should only be considered as a last step in any enterprise-architecture maturity model. Robustness considerations should come first.

Among companies that tried to implement SOA, many did not need it in the first place. Companies that do not benefit from flexible business processes have no reason to switch to a service approach, as this will incur heavy financial and organizational risks for an often unpredictable outcome.[…]

[…] It remains true, however, that, independently of any flexibility considerations, a service approach can still be partly motivated by reuse considerations, as an implementation of simplicity through reduction and simplicity through organization principles.

Как своего рода альтернатива SOAP появился REST (simpler, lightweight, and cost-effective). Основными потребителями REST считались и считаются люди, а не компьютеры, появилась пользовательская композиция (mashups) и произошло отделение решений на базе семантики (планирование, формализация) от решений на базе workflow (mashup, bpel4rest). — сложный текст

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

  • self-configuring
  • self-optimizing
  • self-healing
  • self-adapting
  • IoT
  • Prosumers

Микросервисы появились в ответ на эти вызовы как решение enterprise-уровня. При этом авторы ссылаются на статью Microservices vs. service-oriented architecture Марка Ричардчcа, где отличия SOA и Microservices лежит в плоскости лежащих в их основах идей: SOA реализует идею  share-as-much-as-possible, микросервисы в свою очередь – share-as-little-as-possible.

share-as-little-as-possible

«the goal became how to build systems that are replaceable while being maintainable»

О том же пишет и Мартин Фаулер:

The key property of a component is the notion of independent replacement and upgradeability — which implies we look for points where we can imagine rewriting a component without affecting its collaborators[…]

[…]This emphasis on replaceability is a special case of a more general principle of modular design, which is to drive modularity through the pattern of change. You want to keep things that change at the same time in the same module. Parts of a system that change rarely should be in different services to those that are currently undergoing lots of churn. If you find yourself repeatedly changing two services together, that’s a sign that they should be merged.

Возвращаясь к обозначенным ранее свойствам микросервисов авторы делают вывод, что микросервисы хорошо подходят для сценариев со слабой интеграцией данных и высокой динамикой процессов, что, согласно изложенному в Managing Complexity of Information Systems — 2012 — Lemberger — Why Has SOA Failed So Often и дает возможность быстро внедрять инновации.

FaaS / Serverless

Несмотря на то, что статья отражает путь эволюции к микросервисам, авторы затрагивают и технологию FaaS (function-as-a-service) как следующий шаг в развитии. FaaS выражает в себе те же принципы, что микросервисы: isolation, interchangeability, но отличается в подходах к следованию им:

  • Обрабатывает запросы без предварительного выделения каких-либо вычислительных мощностей;
  • Запросы выполняются в управляемых провайдером контейнерах, которые стартуют по событию и эфемерны (могут существовать только один вызов).

Этот подход позволяет писать и развертывать код без учета среды выполнения, распределения ресурсов, балансировки нагрузки и масштабируемости; всеми этими аспектами занимается провайдер.

Serverless vs Others
Serverless vs Others

Serverless — это эволюция pay-per-use:

  1. Virtual Machines (EC2)
  2. Containers (Docker)
  3. Ресурсы на время, необходимое для выполнения вычислений, обычно несколько секунд или миллисекунд

Выгоды очевидны:

  • Экономия (модель pay-per-use с гранулярностью 100 ms у основных вендоров)
  • Функции используют единую среду выполнения (обычно пул контейнеров)
  • Мало кода и stateless by design
  • Горизонтальное масштабирование полностью автоматическое, эластичное и быстрое

Все это упрощает масштабируемость и деплой, требующие серьезных усилий в микросервисной архитектуре.

Разумеется, FaaS/Serverless несет с собой и новые вызовы:

  • Требуются методы поиска мест, в которых FaaS может принести экономическую выгоду
  • Обеспечение изоляции между функциями
  • Корректный уровень гранулярности при раскрытии данных и кода
  • Работа с состоянием при том, что функции по-определению stateless
  • Рост количества инструментов для локального деплоя и тестирования

FaaS/Serverless не подойдет, если:

  • Требуется собственная инфраструктура (требования регулятора или компании)
  • Требуется реализация длительных операций (например, транзакций)
  • Требуется избежать vendor lock (у каждого провайдера свой serverless API и SDK)
  • Требуется использовать инфраструктуру еще и под иные нужды

Примеры

  • AWS Lambda
  • Azure Functions
  • Google Firebase

Open Source решения

  • IBM/Apache Openwhisk
  • Quarkus
  • OpenFaaS

Сложность

Эволюционный взгляд позволяет увидеть, что нового привнесли микросервисы и какие принципы и концепции SOA все еще применимы.

Сложность дизайна

Несмотря на лавинообразное распространение микросервисов (microservitization), авторы указывают на недостаток академических работ в области практик и паттернов проектирования микросервисов. Похоже на то, что использование принципа «design for failure» и паттернов устойчивости (resilience), вроде circuit-breaker и bulkhead, помогают получить такие качества, как:

  • responsiveness (используя модель «let-it-crash»)
  • fault tolerance
  • self-healing
  • variability characteristics

Так же исследовательский интерес представляет оценка влияния проектирования на основе stateless-функций на эластичность и масштабируемость.

Другая сложность – это подходящий уровень гранулярности микросервиса. Это очевидным образом ведет к компромиссу между размером и количеством микросервисов. Больше микросервисов – выше изоляция бизнес-функциональности, но, – ценой увеличения накладных сетевых расходов и возрастания сложности распределенной системы.

Друга сложность – «security by design». Из-за большого числа небольших сервисов и endpoint’ов поверхность атаки в микросервисной архитектуре значительно больше, чем в SOA. Здесь контроль доступа играет решающую роль, так как каждый микросервис должен иметь возможность быстро устанавливать происхождение и подлинность каждого запроса, что сложно сделать в распределенной системе.

Сложность разработки

Большинство микросервисов сегодня взаимодействуют посредством RESTful HTTP (заявление актуально на 2015 год). Взаимодействие посредством сообщение выглядит многообещающим, но имеет слабую распространенность (а это актуально и сегодня, почти 8 лет спустя). API становится своего рода контрактом, увеличивающим связанность (coupling) и нарушение которого ведет к невозможности взаимодействия сервисов друг с другом.

Таким образом можно выделить две сложности со взаимодействием сервисов:

  • Одновременная поддержка нескольких версий API в процессе разработки
  • Обратная совместимость и/или поддержка старых версий API в проде

В статье рекомендуется посмотреть на OpenAPI (весьма ценная рекомендация 🙂 ).

Другая сложность – согласованность данных вследствие того, что база данных может быть частью реализации микросервиса. Один из вариантов решения – eventual consistency, несмотря на неприменимость в некоторых доменах и сложность реализации. Так же распределенная природа данных в микросервисах усложняет распределенные транзакции и запрос данных при необходимости собрать данные из нескольких сервисов.

На 2022 год у обеих сложностей есть подходящие решения. Мы проектируем решение таким образом, чтобы в нем не было необходимости в распределенной транзакции. Обычно такая транзакция – это следствие нарушения cohesion на уровне всей системы, то есть когда неделимое целое с точки зрения целостности данных разделили на несколько «независимых» частей. Для решения сложности запроса данных можно использовать паттерны Backend For Frontend и/или CQRS.

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

Сложность эксплуатации

Сложности эксплуатации в основном связаны с потреблением вычислительных и сетевых ресурсов.

Больше сервисов:

  • Больше сред одновременно в рантайме
  • Больше удаленных вызовов

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

Операционная сложность напрямую следует из распределенной и динамичной природы решения на микросервисах:

  • Гибкое масштабирование в обе стороны (scale in / scale out)
  • Миграция с одного хоста на другой

Можно дополнить этот список:

  • Одновременное выполнение нескольких версий одного сервиса при постепенном развертывании
  • Независимое друг от друга развертывание сервисов
  • Внезапное падение или замедление любого сервиса в любой момент

Выводы

Основные сложности в микросервисах связаны с относительной новизной явления, внутренней сложностью и распределенной природой. Особенности дизайна, разработки и эксплуатации связаны с сильной распределенностью бизнес-логики по независимым, асинхронно эволюционирующим микросервисам.

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

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

Одним из следствий этой эволюции является разработка новых архитектурных паттернов и появление и применение новых стандартов. Авторы считают, что для достижения высокого уровня interoperability и compatibility важнейшим направлением является разработка и применение открытых стандартов (например – документирование RESTful APIs с помощью спецификаций Swagger/OpenAPI). Стандартизация описания сервиса и хореографический подход к взаимодействия могут обеспечить совместимость любых сервисов и улучшить их evolvability.

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


Конечно, история микросервисов на этом не заканчивается, как не заканчивается и сама статья. Дальше в статье авторы анализируют разные репы на GitHub и приводят свои наблюдения. Я не увидел высокой ценности в переводе этой части (соотношение затраты/ценность), так что интересующимся предлагаю ознакомиться самостоятельно.

Ссылки на другие материалы по теме микросервисной архитектуры с этого блога:

Мой курс по проектированию микросервисов, на котором мы вместе проектируем решение на основе микросервисного архитектурного стиля, закрепляя теорию практикой.

Share

Добавить комментарий