От хаоса к порядку: как легко интегрировать сервисы с помощью Enterprise Service Bus

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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

Чтобы упростить весь этот процесс, существует Enterprise Service Bus — архитектура, которая помогает навести порядок и облегчает межсервисное взаимодействие. 

Всем привет, меня зовут Даниил Солодухин, я программист в студии ITT. В этом тексте я расскажу про особенности ESB, а также объясню, чем она полезна в работе.

Много сервисов — много проблем

Прежде чем перейти к обсуждению ESB, давайте определимся с проблемой. Представьте, что у вас есть система из большого количества сервисов — каждый занимается чем-то своим, предоставляет часть функциональности всей системы. Какой-то занимается авторизацией, другие хранят пользователей, историю, данные кредитных карт и так далее. Это могут быть не микросервисы, а достаточно большие монолиты. Для нас разницы нет. 

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

 

Чтобы добавить пикантности схеме, напомню, что еще протоколы могут быть разными. Часть сервисов умеют работать по HTTP, часть используют JMS, часть применяют файловый ввод-вывод (они ждут файлов в определенных каталогах на своем сервере), а какие-то компоненты этой схемы вообще общаются по e-mail. 

Если вы думаете, что я нагнетаю обстановку — нет. Это реальная картина, я с этим сталкивался: такое бывает, когда у вас достаточно старая система — сервисы вводили в строй в разное время, разными командами. И еще хуже, когда сервисы не ваши, а какие-то сторонние, и вам надо с ними общаться. Вы никак не можете повлиять на то, какие API, какие протоколы они будут использовать. Подобный хаос встречается повсеместно. 

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

На картинке ниже представлено схематичное изображение всех собранных в книге паттернов. Наверное, вы увидите там некоторые знакомые термины: например, Message Bus, Channel, Message, Router, Point. Сейчас многие из нас пользуются этими паттернами в повседневной разработке, воспринимая их как нечто естественное и само собой разумеющееся, а все это пришло к нам оттуда. 

Используя эти паттерны, мы можем превратить нашу хаотичную систему в нечто красивое и понятное. 

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

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

Что такое ESB

ESB — это подход к решению задачи интеграции, некоторый набор принципов, правил, паттернов и того, как ими пользоваться. Архитектура ESB ориентирована на сервис. Соответственно, она event-driven, то есть мы ориентируемся на то, что мы общаемся с нашими сервисами через сообщения — мы их посылаем и получаем. 

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

С другой стороны, ESB — это конкретное программное обеспечение. Возникает своеобразный дуализм понятия — это и архитектура, и в то же время ПО.

Вот небольшой список самого известного middleware ПО, реализующего архитектуру ESB:

  • IBM IIB

  • Red Hat JBoss Fuse

  • Mule ESB

  • Oracle Service Bus

  • Apache ServiceMix

  • Apache Camel

Я отдельно выделю Apache Camel — его постоянно включают в список популярных ESB-решений, но дело в том, что он не является ESB. Apache Camel — это фреймворк для разработки интеграционных решений, в том числе и для разработки ESB. Более того, Apache ServiceMix и Red Hat JBoss Fuse используют Apache Camel как составную часть своего решения, которое в целом уже является ESB. 

Что предлагает нам ESB 

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

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

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

Получается, что от сервисов скрыта внутренняя кухня: они не обязаны знать, кто как работает, их задача — отправить сообщение на шину. Соответственно, если у нас один из сервисов меняет протокол, к примеру, был HTTP, стал JMS, то нам надо поправить это в одном месте — на самой шине. 

Количество протоколов, которые поддерживает шина, зависит от конкретных решений. Например, IBM ESB поддерживает много вариантов, Sprint Integration — мало. Подсчитать точные значения может быть сложно. Но тот же Camel заявляет, что в целом поддерживает порядка 250 различных протоколов и вариантов трансформации данных. Помимо распространенных, Camel поддерживает, например, Slack, Jira. То есть вы можете из вашей ESB создавать задачи в Jira. 

Data Transformations. Даже если мы пользуемся одним протоколом, у нас могут быть разные форматы данных — один сервис может предоставлять ответ в формате XML, второй — в Json, третий вообще в бинарном формате. Все это надо как-то преобразовать, чтобы разные сервисы понимали друг друга. Эту задачу ESB тоже берет на себя.

Многие ESB предоставляют достаточно удобные графические инструменты для Data Transformations. Например, у вас с одной и с другой стороны XML, но при этом разные XSD. Вы открываете графический инструмент и там наглядно показано, как все работает. 

Вот так выглядит Data Transformations в графическом представлении. Я взял пример из Red Hat JBoss Fuse. 

C одной стороны входящие данные, с другой — исходящий формат сообщений. Между ними можно настраивать маппинг из одного типа в другой. 

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

Еще можно добавить мультиплексирование, чтобы одно сообщение разослать нескольким клиентам. Причем можем отправить сразу всем или какому-то конкретному списку.

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

Другая возможность — добавление условных маршрутов. К примеру, пришло какое-то сообщение, а там нет нужного поля, поэтому мы не будем его дальше обрабатывать. Также на уровне ESB можно встроить Load Balancer — Round-robin, Failover и так далее. 

Вот пример маршрутизации с помощью Red Hat JBoss Fuse. 

Здесь достаточно простая логика. В файле мы что-то прочитали. Дальше идет элемент Choice, то есть какой-то выбор, куда нам направить. И в зависимости от параметров мы можем отправить наше сообщение по одному или по другому пути. 

Гарантированная доставка сообщений. Если сообщение было отправлено, то получатель его обязательно получит. Даже если его в тот момент не было «в живых», то когда он появится и подключится к ESB, ему это сообщение все равно доставят. 

Здесь надо сделать небольшую ремарку. Camel не гарантирует эту доставку — если некому доставить, сообщение пропадет. Никто хранить его для вас не будет. Если вы пользуетесь Camel и хотите получить полноценную ESB, вам придется самим обеспечивать гарантию доставки. 

Мониторинг. ESB позволяет в целом посмотреть, как у вас идет процесс: где в данный момент находится сообщение, куда уходит, помогает собирать статистику и так далее. Все это доступно из коробки (но не в Camel).

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

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

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

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

У каждого элемента на графической схеме есть свой ID в виде порядкового числа. Если на схеме 100 элементов, а вы добавляете еще один, у вас появляется 101 элемент. Если вы добавите еще один, это будет 102 элемент. Соответственно, если два человека одновременно добавляют элементы, то у одного будет ID 101 и у второго будет ID 101. И когда вы начнете это мержить, то не факт, что Git вообще это воспримет как конфликт. А потом вы запустите приложение и обнаружите, что оно у вас не работает. Это только один пример, на самом деле там много возможностей для ошибки.  

Мы в какой-то момент пришли к тому, что нельзя делать так, чтобы двум людям одновременно падали задачи, которые подразумевают исправления самого процесса. То есть надо заранее запланировать и декомпозировать задачи: чтобы один писал Java-код, а второй занимался исправлением схемы. К сожалению, пришлось изворачиваться. Если у вас большая команда (более десяти человек), вы, наверное, не сможете так сделать. Я так и не нашел нормального решения. Видимо, все так или иначе страдают. 


Когда ESB стоит его использовать? Когда у вас много сервисов, все они имеют разные протоколы, разные форматы данных, а логика интеграции достаточно сложная. 

Одна из самых приятных возможностей, которые дает ESB, это простое масштабирование этих систем. Если вы добавляете какой-то сервис, то будет достаточно изменить код или схему всего в одном месте. Вы можете в любой момент поменять сервисы, например, перейти с HTTP на JMS. И это повлияет только на сам сервис и на шину. Остальные части системы могут вообще не знать о том, что что-то изменилось. И это удобно. 

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

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

Источник: https://habr.com/ru/company/mygames/blog/671496/


Интересные статьи

Интересные статьи

Исследователям из Объединенного института ядерных исследований (ОИЯИ) удалось подтвердить негативное влияние радиации на когнитивные функции и морфологическое строение мозга грызунов.Сотрудники Л...
Любой алгоритмический процесс может быть автоматизирован, обычно для автоматизации рутинных задач пишутся скрипты, которые принимают определённые параметры, делают определённые действия, и возвращают ...
Электромагнитные поля - загадочные и интересные. Мы давно покорили их и они несут нам верную службу во всех областях науки и техники. Но и по сей день главным вопросом, который больше всего всех волну...
В этой статье я расскажу про атаку PetitPotam, которая позволяет при определенных условиях захватить контроллер домена всего за несколько действий. Атака основана на том, что можно заставить контролле...
Время от времени нам приходится писать статьи о проверке очередной версии какого-то компилятора. Это неинтересно. Однако, как показывает практика, если этого долго не делать, люди начин...