среда, 6 ноября 2013 г.

Event-Driven Architecture на Oracle SOA Suite 11g - компонент Event Delivery Network (EDN)

Термин "управляемая событиями архитектура" (Event Driven Architecture, EDA) предложил Roy W. Schulte, аналитик Gartner в работе The Growing Role of Events in Enterprise Applications, опубликованной в 2003-м году. Одно время подход с архитектурой, управляемой событиями, рассматривали чуть ли не как замену сервисно-ориентированной архитектуре (Service-Oriented Architecture, SOA), существовал даже термин SOA 2.0. В последнее время интерес к EDA поутих, но на мой взгляд у данной концепции есть будущее. В своей заметке четырехлетней давности - Событийная модель построения приложения - Суровый пытался рассказать что такое EDA и какие компоненты необходимы для построения архитектуры, управляемой событиями, в данной же заметке рассмотрим средства, предоставляемые для этого программным продуктом Oracle SOA Suite 11g.

Сначала давайте рассмотрим зачем вообще могут быть нужны события в вашей реализации сервисно-ориентированной архитектуры. Что дает внедрение EDA простому разработчику? Прежде всего это полное разделение между системой-источником событий и системами-приемниками, что по-английски называется Super Decoupling. Что это значит? В классической SOA клиент сервиса должен знать конечную точку, предоставляемую или провайдером сервиса, или сервисной шиной предприятия. Таким образом и при смене конечной точки, и при подключении новой системы-приемника сообщений клиента необходимо изменить, как минимум перенастроить. В случае же управляемой событиями архитектуры, единственное, что должен сделать клиент - опубликовать событие. Он не должен даже знать, есть ли вообще сервисы-обработчики данного события и сколько их.

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

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


Event Delivery Network (EDN)


Вернемся теперь к продукту Oracle SOA Suite. В состав данного продукта входит компонент Event Delivery Network, являющийся диспетчером событий. Данный компонент позволяет различным композитам обмениваться событиями друг с другом. При этом у каждого типа события может быть как несколько источников, так и несколько подписчиков. Обмен событиями реализуется с помощью действий "опубликовать событие" у компонентов Mediator и BPEL Process и специальных точек входа "подписаться на событие" у компонента Mediator, а так же типа взаимодействия (Interaction Type) Event у партнерской ссылки BPEL Process'а. Помимо публикации событий с помощью SCA-компонентов, EDN предоставляет PL/SQL-, Java- и Oracle ADF-BC API для публикации событий. Так же опубликовать событие для тестирования можно с помощью консоли управления Oracle Enterprise Manager Fusion Middleware Control.


Стоит отметить, что в состав Oracle SOA Suite входит две реализации EDN. Одна реализация основана на использовании механизма Oracle Streams Advanced Queuing - специфичной для СУБД Oracle реализации очередей сообщений. Данная реализация включается по-умолчанию при развертывании Oracle SOA Suite с использованием СУБД Oracle. Другая реализация основана на старых-добрых JMS-очередях и использует реализации WebLogic JMS или WebSphere в зависимости от того, на базе какого сервера приложений установлен Oracle SOA Suite.

Помимо физической транспортировки событий по системе, EDN предоставляет механизм описания формата содержимого событий (payload). События в Event Delivery Network описываются с помощью языка Event Definition Language (EDL), являющегося подмножеством языка XML. В состав плагина Oracle SOA Composite Editor интегрированной среды разработки Oracle JDeveloper входит визуальный редактор EDL-файлов, с которым мы познакомимся позже. Код на языке EDL выглядит следующим образом:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://schemas.oracle.com/events/edl" targetNamespace="http://schemas.oracle.com/events/edl/EmployeeEventDefinition">
    <schema-import location="xsd/employee.xsd" namespace="http://www.example.org"/>
    <event-definition name="Employee">
        <content xmlns:ns0="http://www.example.org" element="ns0:Employee"/>
    </event-definition>
</definitions>

С помощью тега schema-import в файл импортируются XSD-описания форматов данных, а с помощью тега event-definition/content формируется содержимое события. В одном EDL-файле может быть описано несколько событий.

От теории к практике - публикация событий


Разработаем небольшой композит, который выставляет веб-сервис, публикующий события в EDN. Для публикации событий будем использовать компонент Mediator.

Создадим SOA-проект SimplePublisher


включающий в себя композит SimplePublisher, содержащий компонент Mediator.


В медиаторе укажем, что определим интерфейс позже, т.к. нам необходимо еще разработать XSD-формат данных и описать событие с помощью EDL.


Создадим новую XSD-схему, назовем ее employee.xsd.


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


Теперь определим в медиаторе сервис, с помощью которого он будет принимать данные о сотруднике от системы-источника. Для этого в мастере настройки медиатора (редакторе .mplan-файлов) необходимо нажать на большой зеленый плюс напротив параметра WSDL URL, а в появившемся окне Define Service нажать на шестеренку.


В появившемся окне Create WSDL нас интересует параметр Interface Type, который необходимо перевести в режим One-Way Interface, т.к. мы реализуем обмен событиями. Так же в параметр Input необходимо добавить часть, содержащую описанный нами ранее элемент Employee.


После нажатия на кнопку OK возвращаемся в окно Define Service, в котором уже будет выбран только что созданный WSDL-документ.


Теперь необходимо создать точку входа в наш композит. Для этого в поле Exposed Services с палитры компонентов необходимо перетащить адаптер Web Service и настроить, указав созданный на предыдущем шаге WSDL-документ.


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


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


Нам будет предоставлено окно Event Chooser, в котором необходимо с помощью кнопки с изображением молнии создать новое событие на основе написанного нами ранее XSD-файла.


Описание события создается с помощью визуального редактора EDL-файлов, представляющего собой окно Create Event Definition File. В данном окне необходимо задать название файла, пространство имен, а так же с помощью кнопки Add Event добавить описания событий.


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


В результате EDL-файл в визуальном редакторе будет выглядеть следующим образом:


Ну и, возвращаясь к медиатору, продемонстрируем заполненный диалог Event Chooser:


Последний шаг в настройке операции в медиаторе - создание трансформации между входом - веб-сервисом - и выходом - описанным нами событием. Если нажать на кнопочку напротив операции Transform Using, то станет доступным диалог настройки трансформации. Нам необходимо создать новый XSLT-файл, поэтому необходимо отметить пункт Create New Mapper File.


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


В редакторе композита справа от медиатора появится значок молнии, что информирует о настроенной публикации события с помощью данного медиатора, в теле самого медиатора в таблице Published: будут перечислены публикуемые события, в нашем случае - событие Employee.


Развернем композит SimplePublisher в среде Oracle SOA Suite. После этого зайдем в дерево композитов с помощью Oracle Enterprise Manager'а и перейдем на страницу свежеопубликованного SimplePublisher. Как видим у данного композита пока еще нет экземпляров.


Протестируем публикацию событий. Т.к. мы создали точку входа в композит в виде веб-сервиса, то на странице композита в Enterprise Manager'е нам доступна кнопка Test. При нажатии на данную кнопку появится форма заполнения запроса, в нашем случае - структуры Employee. Зададим идентификатор сотрудника, его имя и фамилию, а так же зарплату.


После нажатия на кнопку Test Web Service мы получим пустой ответ, т.к. наш веб-сервис реализует взаимодействие по схеме Fire-and-forget.


В окне композита станет доступен для анализа созданный и успешно отработавший экземпляр.


Нажмем на ссылку с идентификатором экземпляра и перейдем в окно трассировки, увидим последовательность операций, которые были выполнены композитом. Нас интересует операция Published event.


Так как данная операция присутствует, то событие было опубликовано в EDN.

Публикация события с помощью Fusion Middleware Control


С целью тестирования подписчиков на события не обязательно создавать композиты для публикации, ведь в реальном приложении для создания событий может использоваться помимо SOA Suite - PL/SQL- или Java API. В состав консоли управления Oracle Enterprise Manager Fusion Middleware Control входит тестовый публикатор событий. Данный публикатор присутствует на странице Business Events, доступной из контекстного меню элемента soa-infra дерева домена.


На странице Business Events присутствуют три вкладки: Events, на которой отображаются все зарегистрированные в EDN описания событий, Subscriptions, на которой присутствует информация о подписчиках и Faults, на которой перечислены ошибки обработки событий.


При выборе конкретного события из списка Namespaces and Events на вкладке Events становятся доступны кнопки Subscribe..., Test... и Show Event Definition. Нас интересует кнопка Test... При нажатии на данную кнопку появляется окошко Test Event. В данном окне необходимо заполнить поле Event Payload, записав туда содержимое события. К сожалению визуальный редактор для содержимого события не предусмотрен, туда надо скопировать чистый XML, с данными события.


После нажатия кнопки Publish событие будет опубликовано в EDN, о чем нас уведомят с помощью окна информации.


Подписка на события с помощью медиатора


Публиковать события в EDN смысла не много, если отсутствуют подписчики. Давайте разработаем подписчика на события с помощью компонента Mediator. Для этого с помощью JDeveloper создадим SOA-проект SimpleMediatorSubscriber


содержащий композит с компонентом Mediator.


Медиатор настроим следующим образом. В качестве шаблона выберем Subscribe to Events.


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


С помощью кнопки с изображением лупы выберем созданный ранее файл EmployeeEventDefinition.edl и описанное в нем событие Employee.

После нажатия кнопки OK появится мастер переноса EDL- и связанного с ним XSD-файла в каталог нашего композита-подписчика. Необходимо согласиться и нажать кнопку OK.


В таблице событий, на которые подписывается создаваемый медиатор, появится строчка с событием Employee. Помимо названия события в данной таблице присутствуют колонки Consistency, Run as publisher и Filter. Данные поля задают режимы подписки на события. Рассмотрим их подробнее.

Поле Consistency отвечает за управление транзакциями при подписке на события. Т.е. по-сути за то, как будут обрабатываться сбои при обработке событий. Данный параметр может принимать одно из трех значений:

- one and only one - гарантированная обработка событий. Подписчики работают в рамках JTA-транзакций, можно настроить повторную обработку событий при сбое в подписчике. Каждый подписчик работает в своей транзакции, сбой в работе одного подписчика не влияет на другие. Количество попыток повторной обработки событий задается настройками AQ- или JMS- очередей в зависимости от используемой реализации EDN. Однако, на практике общее число попыток, включая первый вызов подписчика, ограничено четырьмя, даже если в настройках очередей указано больше попыток. Как увеличить лимит повторов найти не удалось.

- guaranteed - подписчик считывает событие из очереди в отдельной локальной транзакции. Повторные попытки обработки события при сбоях не производятся.

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

Поле Run as publisher отвечает за то, будет ли подписчик работать в том же контексте безопасности, что и публикатор. Может принимать два значения: yes и no.

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


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


Развернем композит с подписчиком в среде Oracle SOA Suite. На странице композита в Enterprise Manager мы видим отсутствие созданных экземпляров.


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


Вернемся на страницу подписчика. Мы увидим, что был создан и успешно завершен экземпляр подписчика на событие.


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


Таким образом видно, что EDN работает и наши события передаются от публикаторов к подписчикам!

Подписка на события с помощью компонента BPEL Process. Настройка фильтрации


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

Чтобы продемпонстрировать работу с событиями в BPEL создадим новый SOA-проект SimpleBpelSubscriber


содержащий компонент BPEL Process.


При настройке BPEL укажем шаблон Subscribe to Events, уберем галочку Expose as a SOAP Service, т.к. наш процесс будет запускаться по событию, а не по вызову веб-сервиса. В нижней части окна настройки появится поле для выбора событий, на которые должен быть подписан процесс. Выберем событие Employee, аналогично тому как мы делали при настройке медиатора.


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


Если два раза нажать на символ BPEL-процесса, то откроется редактор, в котором будет видно, что точка входа в процесс срабатывает по событию - ее символ перечерчен знаком молнии.


В примере с медиатором мы не использовали поле Filter. Давайте теперь настроим фильтрацию для событий, на которые подписывается наш BPEL-процесс. Для этого надо щелкнуть два раза по молнии на значке BPEL, при этом откроется окно редактирования подписки на событие. При двойном щелчке в поле Filter откроется визуальный редактор выражения, которому должны удовлетворять события, чтобы быть обработанными BPEL-процессом. Например, нас интересуют сотрудники с зарплатой более 100 000. Для доступа к данным события в левой части редактора присутствует переменная be:business-event, в поле be:content которой доступны бизнес-данные события.


В результате, после раворачивания композита в среде Oracle SOA Suite, при передаче сотрудников с зарплатой более 100 000 будут создаваться экземляры и медиатора, и вновь созданного бизнес-процесса.



При передаче меньшей зарплаты будет срабатывать только медиатор.



Фильтрация событий работает!

Заключение


В данной статье мы рассмотрели использование средства для построения управляемой событиями архитектуры на базе программного продукта Oracle SOA Suite - Event Delivery Network (EDN). Данное средство позволяет полностью разделить источник запросов и их обработчики друг от друга, единственное связующее звено, которое остается, это формат событий, задаваемый с помощью языка Event Definition Language (EDL). Возникает закономерный вопрос: а зачем вообще нужен EDN, если обработку сообщений можно реализовать с помощью технологических адаптеров - AQ или JMS - самостоятельно? Действительно, в композите-публикаторе вполне можно просто класть сообщения в JMS-топик, а в подписчиках - считывать из данного топика. Более того, т.к. поддержка гарантированной доставки в EDN реализована весьма условно, то зачастую так и приходится делать. Но с другой стороны, EDN избавляет нас от забот о транспортном уровне. Нам все равно как ходят наши события по системе. Все что нам нужно - определить тип и содержимое события и реализовать их публикацию и подписку с помощью BPEL или медиатора. Уместно провести аналогию между использованием EDN и явным использованием очередей, как между использованием языков высокого уровня, например Java, и ассемблером или между использованием протокола TCP/IP и самостоятельной реализацией транспорта для обмена сообщениями на низком уровне. В редких случаях необходимо поработать руками, но для решения подавляющего большинства задач достаточно готового инструмента, нужно только научиться им пользоваться.

Понравилось сообщение - подпишитесь на блог

9 комментариев:

stepan kachan комментирует...

Большое спасибо за статью , нашел много познавательной информации. Я новичок в данной сфере , и Ваш блог очень сильно мне помогает в обучении.

Pavel Samolisov комментирует...

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

stepan kachan комментирует...

Также было бы интересно узнать о расширенных возможностях Business Rules.

Pavel Samolisov комментирует...

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

stepan kachan комментирует...

Заранее благодарен.

Mikhail Baturov комментирует...

так понял что решение для очень большого предприятия или организации.
Для всего остального подойдет простенький guava bus: https://code.google.com/p/guava-libraries/wiki/EventBusExplained

Pavel Samolisov комментирует...

Для всего остального - это получается или для отдельной программы или для небольшого комплекса программ, разрабатываемых одним поставщиком ПО. Конечно, завязываться в таком случае на промышленные решения типа Oracle SOA Suite, IBM WebSphere Message Broker, SAP PI и т.д. нет смысла, т.к. такие решения предназначены для интеграции разнородных систем, да еще и разбросанных по всему предприятию со всеми возможными филиалами.

Спасибо за ссылку.

aser комментирует...

Приветствую, очень познавательная статья. Спасибо за труд.
У нас большая система и много интеграции через сервиса. Около 60 интеграции, около 5000 пользователей. Сервиса запускаем с помощью EDN (очереди создаем из базы dev_soainfra.EDN_Publish_Event). В минуту объявляются очередей больше 300, и системе не справляется. Везде искал как оптимизировать, не нашел. Пробовали ednconfig NumberOfThreads увеличивали до 200, но оракл рекомендует максимум 10.
Можете подсказать что можно сделать чтобы одновременно запускать более 200 разных bpel процессов. Заранее спасибо

Pavel Samolysov комментирует...

Здравствуйте.

Вопрос интересный. Ответить, не видив реальной системы, затруднительно. Общие соображения - возможно помимо увеличения числа потоков нужно увеличить и размер пула соединений с БД. Так же может быть полезным перейти на JMS-очереди вместо AQ, тем самым снизив нагрузку на БД, вот статья по теме: http://biemond.blogspot.co.uk/2011/06/configure-en-test-jms-based-edn-in-soa.html

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

Отправить комментарий

Любой Ваш комментарий важен для меня, однако, помните, что действует предмодерация. Давайте уважать друг друга!