[Перевод] Микросервисы победили. Или не совсем

«Мы хотим сделать систему по учету персонала. Только у наших архитекторов есть требование, что все у нас должно быть на микросервисах». Это, пожалуй, самый бесячий заход, который нам приходится слышать, как разработчику Jmix — платформы быстрой разработки корпоративных веб-приложений. Почему только микросервисы? Какие проблемы, кроме независимого развертывания они решают? Это действительно необходимо для всех типов приложений? Мы, для полного понимания, ни в коем случае не являемся противниками микросервисной архитектуры, однако неистово сопротивляемся слепому следованию «карго культа». Часто случается, что ничего, кроме удорожания разработки, поддержки и эксплуатации такие решения не приносят. Собственно, об этом и пишет Nikolas Frankel, автор статьи, перевод которой представлен ниже.

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

Вы не работаете с микросервисами

Похоже, что микросервисы сейчас везде. В названии конференции должны фигурировать микросервисы, иначе она не привлечет к себе так много участников. А какие-то конференции и вовсе посвящены только микросервисам. Если говорить о разработчиках, то Hype-Driven Development (она же разработка, основанная на хайпе, или HDD) уже достигла своего апогея. Каждому разработчику нужно указывать в резюме «микросервисы». В противном случае, их могут даже не рассматривать на какую-то должность. Я постоянно твержу, что наша отрасль сошла с ума: большинство тенденций продиктованы хайпом, а не здравым смыслом. Прежде, чем мы продолжим, необходимо определить, что такое микросервисы. Я ограничусь цитатой Мартина Фаулера, поскольку она отражает самую суть.

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

Микросервисы. Определение этого нового понятия в архитектуре

Далее в статье описываются характеристики микросервисов:

  • компонентизация в виде сервисов (оно же: представление через компоненты);

  • выстраивание вокруг бизнес-потребностей;

  • умные конечные точки и тупые каналы;

  • децентрализованное система управления;

  • децентрализованное управление данными;

  • автоматизация инфраструктуры;

  • страховка от сбоев;

  • эволюционный дизайн;

  • продукты, а не проекты.

В общем и целом, все выглядит вполне неплохо, пока мы не доходим до последнего пункта. Проект и продукт — вещи совершенно разные. У проекта есть запланированная дата завершения, а продукт будут разрабатывать до тех пор, пока не решат вывести из эксплуатации (иначе говоря, свернуть). Как это в реальности: большинство организаций планируют проекты. То есть они не могут заявлять, что создают микросервисы (если, конечно, не захотят доказать неправоту Фаулера). До начала всей этой шумихи с микросервисами писатели и спикеры старались объяснить закон Конвея:

Любая организация, которая разрабатывает систему (в широком смысле), создает проекты, структуры которых являются копией структуры связей организации.

Мелвин Э. Конвей

Следовательно, если вы хотите спроектировать микросервисную архитектуру, но нужно выстраивать свою организацию вокруг небольших команд. И такой подход действительно задокументирован в Amazon Web Services:

«Мы стараемся создавать команды такого размера, чтобы их можно было бы накормить двумя пиццами», — сказал Безос: «Мы назвали это правилом «команды на две пиццы».

Команды на две пиццы

Основная идея «команды на две пиццы» заключается в том, что для достижения максимально возможной производительности команда должна быть как можно более независимой. Для таких команд характерна самоорганизованность и автономность. По закону Конвея, если организация сформирована из «команд на две пиццы», то со временем она непременно перейдет к микросервисной архитектуре. Возникает наивный вопрос: неужели компании, в которых реализованы микросервисы, состоят из небольших автономных команд? К сожалению, традиционные компании по-прежнему формируются из разобщенных подразделений. А единственный способ достичь приличных результатов с микросервисной архитектурой — это выстроить организацию вокруг них. Но это масштабное изменение организационной структуры! На него нужно время, готовность пойти на такой шаг, а также специализированная помощь со стороны экспертов по изменению стратегии управления.

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

Время поставки

Одном из своих постов Фаулер упоминает плюсы и минусы микросервисов:

0de0c15711bb9fe4e091bbc332a7a499.png

На мой взгляд, главная причина для перехода на микросервисы — это независимое развертывание:

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

  • Технологическое разнообразие может удовлетворить технические амбиции некоторых сотрудников. В то же время оно наносит ущерб всей организации в целом, затрудняя найм, обучение и снижая т.н. «фактор кирпича» (Примечание от автора: на англ. bus-factor).

А теперь вопрос: почему так жаждут независимого развертывания? Бизнесу совершенно нет дела до развертывания как такового; ИТ-отдел — это просто огромный черный ящик. В ИТ важны два показателя:

  • Срок реализации — время, которое нужно команде разработки для реализации определенной функции.

  • Время развертывания — время, которое нужно команде интеграции для развертывания готовой реализации в рабочей среде.

Но все это внутренние процессы в ИТ. Бизнес волнует лишь то, сколько времени потребуется на запуск спецификации в производство, а не ее внутренние разбивки. Давайте считать время поставки суммой сроков реализации и времени развертывания.

Сокращение времени доставки — проблема далеко не новая, и в прошлом уже находились другие решения.

Время поставки отличается от времени производства, одного из «золотых» стандартов в DevOps. Время производства включает в себя время спецификации — временную задержку от основной идеи до окончательной спецификации. Мой опыт показывает, что время спецификации сводится к многократным дискуссиям между управленцами и ИТ. Конечно же, во многом это зависит от зрелости организации. И все же, в рамках данной статьи корректнее использовать время поставки.

Обработчик правил

До того, как люди вывели теоретические концепции гибкой методологии и непрерывного развертывания, предприятия развертывали системы по несколько раз в год. Мы называли их «релизными поездами» (Release train). Ведь они и правда похожи на поезда: если какую-то функцию доделали с опозданием, то придется ждать следующего релизного поезда. В зависимости от частот релизов, речь могла идти о паре месяцев или даже полугоде. А бизнес не хотел опоздать на поезд!

Единственными допустимыми изменениями (кроме релизного поезда) были исправления ошибок. Это традиция, проверенная временем: впихнуть в исправленную версию одну-две незначительные доработки, чтобы не приходилось ждать следующего поезда. Бывало, что все получалось, но чаще всего релиз-менеджер (он же страж) накладывал свое вето. Периодически начиналось перетягивание каната между управленцами, которые хотели как можно быстрее перейти к развертыванию, и командой, видевшей в этом какие-то риски. Напряжение между бизнесом и ИТ помогло найти оригинальные решения. Среди которых были обработчики правил:

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

Обработчик правил

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

Пользовательский интерфейс, код маршрутизации и бизнес-логика, не связанная с налогами, остались в самом приложении. Основная идея сводится к тому, чтобы у бизнеса была возможность настроить эти правила в рабочей среде самостоятельно, без вмешательства ИТ. Бизнес-эксперты могут изменять правила вне зависимости от частоты выхода релизов. Конечно, с большими полномочиями приходит и большая ответственность. Бизнес — независим, но страдает от последствий ошибок в конфигурации.

Части кода меняются с разной скоростью

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

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

Кроме того, у этого подхода есть два допущения при проектировании:

  1. Мы можем как-то определить границы модулей на этапе проектирования.

  2. Все части необходимо изменять с разной скоростью.

И то, и то — явное заблуждение.

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

А что, если вместо разбивки на микросервисы, просто «отсечь» часть, которая меняется чаще всего (или хаотичнее)? Так у нас останется тот же монолит за вычетом одной единицы. И для этого модуля будут доступны различные способы реализации:

  • обработчик правил — если вы уже с ними работали и остались довольны;

  • бессерверные функции;

  • «обычные» микросервисы;

  • какой-то другой вариант?

Как отсекать?

Как только вы продумали границы и изолировали модуль для «отсечения» возникает следующая проблема: каким образом это сделать? В одной своей известной статье Мартин Фаулер (опять он!) описывает паттерн «Душитель» (Strangler):

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

Приложение фикус-душитель

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

  1. перенести часть приложения куда-то еще. К примеру, в бессерверную функцию;

  2. в любой момент остановиться.

Самая большая проблема связана с клиентами. Перенос конечной точки HTTP в другое место гарантированно все сломает. Однако с помощью интерфейсного API-шлюза проблема решается на ура. Просто направьте запрос в новое местоположение точки, и все готово.

aeafa532dfe9c21bb869f9c98499fb5d.PNG

Заключение

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

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

© Habrahabr.ru