Блеск и нищета микросервисов

Специалист старается знать все больше о все меньшем, пока не будет знать все ни о чем. А философ узнает все меньше о все большем, пока не будет знать ничего обо всем. Д. Гранин, "Иду на грозу"

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

Начать следует издалека, с «проворной» agile разработки. Бертрану Мейеру в своей статье (оригинал, перевод) [1] удалось выделить в методике то немногое, но действительно полезное, имеющее практический смысл в работе. Удалось, несмотря на достаточно негативный фон, поднятый, в том числе, и самими авторами «Манифеста» ввиду явных провалов, стандартно «объясняемых» недостаточно верным следованием процессу (см. например статьи Энди Ханта, Рона Джеффри и Эрика Мейджера) [2,3,4].

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

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

Наконец, с точки зрения философии UNIX [7], использование множества небольших специализированных программ предпочтительнее крупных интегрированных пакетов и систем. Такой подход также хорошо ложится на разработку микросервисов. Конечно, трудно представить себе транзакционную СУБД или издательскую систему, выполненные в архитектуре из роя монофункциональных утилит командной строки, но, например, конвейерные обработки графических файлов по сценариям пользователя смотрятся в подобной схеме органично.

Упомянутый выше перевод статьи Б. Мейера в «Открытых системах» продолжает ряд материалов о микросервисах, что является наглядной иллюстрацией так называемого цикла хайпа (hype cycle согласно Gartner) [5]: аджайлы опускаются в район точки «избавление от иллюзий», тогда как микросервисы пока еще вблизи пика ожиданий чудес.

Избавление от иллюзий вовсе не гарантирует преодоления недостатков: множество технологий остались забытыми, так и не выйдя на плато продуктивности. Некоторые технологии зрели десятилетиями, подобно, например, .NET, первые промышленные реализации которой относятся к середине-концу 1960-х годов [6].

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

Микросервисы-1 или лоскутное одеяло автоматизации

В 1980-х годах с легкой подачи IBM на предприятия начали массово поступать персональные компьютеры, связанные позднее локальными сетями. Если раньше все приложения работали на одной большой ЭВМ, мейнфрейме, то теперь каждый отдел, а то и специалист, получали в свое распоряжение собственные вычислительные мощности. Разумеется, эти мощности нужно поскорее заполнить накопившимися задачами, уменьшая зависимость от главной ЭВМ, постоянно загруженной обслуживанием критичных для предприятия процессов. Таких задач нашелся «воз и малая тележка». Вдобавок, децентрализация «откусывала» от центральной ЭВМ функции, качеством которых пользователи были недовольны. Для программистов «персоналок» наступила золотая пора, работа закипела на годы. Программисты мейнфреймов, в свою очередь, считали эти занятия несерьёзными.

Типичное приложение того времени: десяток файлов данных, два-три десятка экранных форм ввода и вывода информации, несколько сотен или тысяч строк кода программы. Полностью автономное, развертывающееся простым копированием (copy deployment) позволяло масштабировать горизонтально и повысить надежности. Сломался компьютер? Ерунда, пересаживаемся на другой, всего за четверть часа скопированы программы, вчерашние данные с дискеты восстановлены, пользователь продолжает работу. Обмен информации по файловым протоколам, включая пресловутый floppy net (дискеты) в качестве носителя. Что ни приложение, то настоящий «микросервис» персонально-компьютерной эпохи, для пущей верности спаянный с фронт-эндом.

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

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

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

Микросервисы-2 или тяжелая поступь CORBA

1990-е годы – период эволюции двухзвенных клиент-серверных систем к многозвенным. Потому что прикладную логику надо размещать в таком месте, где её можно повторно использовать с минимальными затратами. Архитектура, превращающая СУБД в сервер приложений из хранимых процедур до сих пор успешно используется, но имеет ряд существенных ограничений, не всегда приемлемых. Поэтому более общий подход – использование промежуточных слоев служб.

Технология CORBA, о развитии и упадке которой написано много и подробно [8,9,10], предлагала стандартизованный подход к построению многослойных распределенных систем: от определения интерфейсов разрабатываемых сервисов до использования готовых стандартных служб, например, именования, оповещения или безопасности. Как и технология веб-служб, CORBA не навязывала дробление на микрокомпоненты, но уже на этапе проектирования интерфейсов и планирования развертывания на многочисленных серверах такая архитектура выглядела вполне естественной. Система, представляющая собой пучок функционально небольших служб, взаимодействующих по общей шине – мечта интеграторов была близка к реализации, выглядевшей по меньшей мере красиво.

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

Эволюция корпоративной фермы микрослужб была похожей на микросервисы-1: компоненты укрупнялись до размеров функциональных подсистем уровня доменов предметных областей. В самом деле, если службы представляют собой функциональные подсистемы, то обработка данных концентрируется внутри. Собственно, на этапе анализа подсистемы и выделяют по признакам сильных и слабых связей между объектами предметной области. Однако такой компонент уже слишком велик, чтобы считаться микросервисом. Можно ли службу расчета зарплаты всерьёз принимать за «микро»?

Тем временем CORBA была вытеснена более простыми (и менее функциональными) архитектурами на основе веб-служб, гоняющих по сети XML и появившийся позднее JSON. Технология сменилась, но сервис-ориентированная архитектура прижилась, хотя от приставки «микро» мало что осталось.

Микросервисы-3 или железной рукой загоним ИТ к счастью в облаках

Подъем из небытия темы микросервисов [11,12,13] совпал с увеличением потока проектов миграции инфраструктур служб ИТ в «облака». В самом деле, идеальный компонент для использования в облаке должен быть полностью автономным и не иметь состояния. В таком случае микросервис можно неограниченно масштабировать по горизонтали для обеспечения постоянной готовности и балансировки нагрузки. Настоящий сферический конь в вакууме, то есть, простите, в контейнере. Почему бы вместе с миграцией не продать клиенту еще и переделку части системы?

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

Тезис о более высокой надежности разработки именно микросервисов, к сожалению, не имеет прямого отношения к технологии, это всего лишь очередное обращение к теме изолированности программного кода. Действительно, вертикальным командам и разработчикам без содействия горизонтальной группы проектировщиков трудно согласовать повторное использование компонентов более низких, подфункциональных уровней. При желании, такую возможность можно даже запретить административно. Достаточно давно на одной из конференций разработчики Microsoft рассказывали, что компоненты форматирования в ячейке Excel и соответствующей таблице Word совершенно независимы. Хотя приходится писать вдвое больше кода, зачастую дублирующего, и тестов, но зато изменения этой функции в Excel не вызовет побочных эффектов в Word. В корпоративной реальности немногие заказчики обладают возможностью многократно платить деньгами и сроками за дублирование «велосипедов», а риски сбоев из-за изменений в других частях системы парируются интеграционными тестами.

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

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

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

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

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

Преодоление или новый провал?

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

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

Литература

1. Бертран Мейер, «Об Agile по гамбургскому счету», Открытые системы №2, 2018, https://www.osp.ru/os/2018/2/13054179/. Оригинал статьи «Making sense of agile methods», ноябрь 2017, http://se.ethz.ch/~meyer/publications/me...
2. Andy Hunt (один из авторов «The Agile Manifesto»), «The Failure of Agile», июнь 2015, https://toolshed.com/2015/05/the-failure...
3. Ron Jeffries (один из авторов «The Agile Manifesto»), «Developers Should Abandon Agile», май 2018, https://ronjeffries.com/articles/018-01f...
4. Erik Meijer, « Agile must be destroyed, once and for all», январь 2015, https://www.theregister.co.uk/2015/01/08...
5. Hype cycle, статья в википедии, https://en.wikipedia.org/wiki/Hype_cycle
6. АЛМО или .NET образца 1967 года, https://www.arbinada.com/ru/node/1333
7. Эрик Рэймонд, «Искусство программирования для Unix», Вильямс, 2016, https://www.ozon.ru/context/detail/id/13...
8. Сергей Тарасов, «Дефрагментация мозга. Софтостроение изнутри», СПб.: Питер, 2013, https://www.ozon.ru/context/detail/id/34...
9. Мичи Хеннинг, «Восход и закат CORBA», ACM Queue, Volume 4, Number 5, June 2006, перевод С. Кузнецова, http://citforum.oldbank.com/SE/middlewar...
10. Дирк Слама, Джейсон Гарбис, Перри Рассел, «Корпоративные системы на основе CORBA», Вильямс, 2000, https://www.ozon.ru/context/detail/id/11...
11. Сэм Ньюмен, «Создание микросервисов», СПб.: Питер, 2016, https://www.ozon.ru/context/detail/id/13...
12. Martin Fowler, James Lewis, «Microservices. A definition of this new architectural term», March 2014, https://martinfowler.com/articles/micros...
13. Андрей Фурда, Колин Фидж, Олаф Циммерманн, Уэйн Келли, Алистер Баррос, «Миграция унаследованных корпоративных приложений на микросервисы», Открытые системы №3, 2018, https://www.osp.ru/os/2018/03/13054403/
14. Sean Kelly, "Microservices – Please, don’t", September 14, 2016, https://riak.com/posts/technical/microse...
15. Dave Kerr, "The Death of Microservice Madness in 2018", https://www.dwmkerr.com/the-death-of-mic...
16. Alexandra Noonan, "Goodbye Microservices: From 100s of problem children to 1 superstar", July 10, 2018, https://segment.com/blog/goodbye-microse...

Статья также опубликована в журнале "ITWeek" 24.01.2019.