Событийно-ориентированная архитектура

Архитектура, управляемая событиями (англ. event-driven architecture, EDA) является шаблоном архитектуры программного обеспечения, позволяющим создание, определение, потребление и реакцию на события.

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

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

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

Архитектура, управляемая событиями, соответствует сервисно-ориентированной архитектуре (SOA), поскольку сервисы могут активироваться триггерами, срабатывающими от входящих событий[2][3].

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

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

Структура события

[править | править код]

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

Уровни потока событий

[править | править код]

Архитектура, управляемая событиями, состоит из четырёх логических слоев. Она начинается с фактического зондирования, его технического представления в форме события и заканчивается непустым множеством реакций на это событие.[4]

Генератор событий

[править | править код]

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

Канал событий

[править | править код]

Канал событий — механизм, по которому передаётся информация от генератора событий к обрабатывающему события механизму[4] или стоку.

Это может быть соединение TCP/IP или входной файл любого типа (простой текст, формат XML, e-mail, и т. д.) В одно и тоже время может быть открыто несколько каналов событий. Обычно из-за требований обработки событий в режиме, приближенном к реальному времени, каналы событий считываются асинхронно. События сохраняются в очереди, ожидая последующей обработки механизмом обработки событий.

Механизм обработки событий

[править | править код]

Механизм обработки событий является местом, где событие идентифицируется и выбирается соответствующая реакция на него, которая затем выполняется. Это также может привести к созданию ряда утверждений. Например, если пришедшее в механизм обработки событие сообщает, что «Продукт N заканчивается», этот факт может породить реакцию «Заказать продукт N» и «Уведомить персонал».[4]

Последующее действие, управляемое событиями

[править | править код]

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

Стили обработки событий

[править | править код]

Существует три основных стиля обработки событий: простой, потоковый и сложный. Часто эти три стиля используются совместно в большой событийно-управляемой архитектуре[4].

Простая обработка событий

[править | править код]

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

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

Обработка потока событий

[править | править код]

При обработке потока событий (event stream processing — ESP) происходят как обычные, так и известные события. Обычные события (команды, передачи RFID) проверяются на известность и передаются информационным подписчикам. Обработка потока событий обычно используется для управления потоком информации в реальном времени и на уровне предприятия, позволяя своевременное принятие решений[4].

Обработка сложных событий

[править | править код]

Обработка сложных событий позволяет рассматривать последовательности простых и обычных событий и делать вывод о наступлении сложного события. Обработка сложных событий оценивает взаимное влияние событий и затем предпринимает действия. События (известные или обычные) могут не соблюдать типизацию и возникать на протяжении длительных временных периодов. Корреляция событий может быть причинной, временной или пространственной. Обработка сложных событий требует использования сложных интерпретаторов событий, определения паттернов событий и их сопоставления, а также корреляционных методов. Обработка сложных событий обычно используется для определения и реакции на аномальное поведение, угрозы и возможности[4].

Экстремальное слабое связывание и хорошая распределенность

[править | править код]

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

Реализации и примеры

[править | править код]

Библиотека Java Swing основана на архитектуре, управляемой событиями. Это особенно хорошо сочетается с мотивацией Swing предоставить компоненты и функциональность, относящуюся к пользовательскому интерфейсу. Интерфейс использует соглашения о наименовании (например, «ActionListener» и «ActionEvent») для организации отношений между событиями. Класс, нуждающийся в оповещении о некотором событии, просто реализует соответствующего слушателя, переопределяет наследуемые методы и добавляется к объекту, порождающему событие. Ниже приведен простейший пример:

public class FooPanel extends JPanel implements ActionListener {     public FooPanel() {         super();          JButton btn = new JButton("Click Me!");         btn.addActionListener(this);          this.add(btn);     }      @Override     public void actionPerformed(ActionEvent ae) {         System.out.println("Button has been clicked!");     } } 

Альтернативой является внедрение слушателя в объект в виде анонимного класса. Ниже представлен пример.

public class FooPanel extends JPanel {     public FooPanel() {         super();          JButton btn = new JButton("Click Me!");         btn.addActionListener(new ActionListener() {             public void actionPerformed(ActionEvent ae) {                 System.out.println("Button has been clicked!");             }         });     } } 

Тот же код в функциональном стиле Java 8, с применением лямбда выражения вместо анонимного класса:

public class FooPanel extends JPanel {     public FooPanel() {         super();         JButton btn = new JButton("Click Me!");         btn.addActionListener(ae -> System.out.println("Button has been clicked!"));     } } 

Серверная JavaScript платформа активно использует генераторы событий (EventEmitter). Множество объектов в Node генерируют события: net.Server вызывает событие при каждом поступающем запросе, fs.readStream вызывает событие при открытии файла. Пример работы с EventEmitter:

bar.js:

var Foo = require("./foo.js").Foo,     foo = new Foo();  foo.addListener("write", function() {     console.log("Bar"); }); 

foo.js:

var EventEmitter = require("events").EventEmitter,     Foo = function() {         var foo = this;         foo.write = function() {             console.log("Foo");             foo.emit("write");         };         setTimeout(this.write, 3000);     };  Foo.prototype = new EventEmitter();  exports.Foo = Foo; 

Примечания

[править | править код]
  1. K. Mani Chandy Event-Driven Applications: Costs, Benefits and Design Approaches, California Institute of Technology, 2006
  2. 1 2 Jeff Hanson, Event-driven services in SOA Архивная копия от 2 июня 2013 на Wayback Machine,Javaworld, January 31, 2005
  3. Carol Sliwa Event-driven architecture poised for wide adoption Архивная копия от 20 марта 2017 на Wayback Machine, Computerworld, May 12, 2003
  4. 1 2 3 4 5 6 7 8 9 10 Brenda M. Michelson, Event-Driven Architecture Overview, Patricia Seybold Group, February 2, 2006