stringtranslate.com

Arquitectura basada en eventos

La arquitectura basada en eventos ( EDA ) es un paradigma de arquitectura de software relacionado con la producción y detección de eventos .

Descripción general

Un evento puede definirse como "un cambio significativo de estado ". [1] Por ejemplo, cuando un consumidor compra un coche, el estado del coche cambia de "en venta" a "vendido". La arquitectura del sistema de un concesionario de coches puede tratar este cambio de estado como un evento cuya ocurrencia puede darse a conocer a otras aplicaciones dentro de la arquitectura. Desde una perspectiva formal, lo que se produce, publica, propaga, detecta o consume es un mensaje (normalmente asincrónico) llamado notificación de evento, y no el evento en sí, que es el cambio de estado que desencadenó la emisión del mensaje. Los eventos no viajan, simplemente ocurren. Sin embargo, el término evento se utiliza a menudo de forma metonímica para denotar el mensaje de notificación en sí, lo que puede dar lugar a cierta confusión. Esto se debe a que las arquitecturas basadas en eventos suelen diseñarse sobre arquitecturas basadas en mensajes , donde dicho patrón de comunicación requiere que una de las entradas sea solo de texto, el mensaje, para diferenciar cómo debe gestionarse cada comunicación.

Este patrón arquitectónico puede aplicarse en el diseño e implementación de aplicaciones y sistemas que transmiten eventos entre componentes y servicios de software acoplados de forma flexible . Un sistema controlado por eventos normalmente consta de emisores (o agentes) de eventos, consumidores (o receptores) de eventos y canales de eventos. Los emisores tienen la responsabilidad de detectar, recopilar y transferir eventos. Un emisor de eventos no conoce a los consumidores del evento, ni siquiera sabe si existe un consumidor y, en caso de que exista, no sabe cómo se utiliza o procesa el evento. Los receptores tienen la responsabilidad de aplicar una reacción tan pronto como se presenta un evento. La reacción puede o no ser proporcionada completamente por el propio receptor. Por ejemplo, el receptor puede tener solo la responsabilidad de filtrar, transformar y reenviar el evento a otro componente o puede proporcionar una reacción autónoma a dicho evento. Los canales de eventos son conductos en los que los eventos se transmiten desde los emisores de eventos a los consumidores de eventos. El conocimiento de la distribución correcta de eventos está presente exclusivamente dentro del canal de eventos. [ cita requerida ] La implementación física de los canales de eventos puede basarse en componentes tradicionales como middleware orientado a mensajes o comunicación punto a punto que podrían requerir un marco ejecutivo transaccional más apropiado [ aclarar ] .

La creación de sistemas en torno a una arquitectura basada en eventos simplifica la escalabilidad horizontal en los modelos informáticos distribuidos y los hace más resistentes a las fallas. Esto se debe a que el estado de la aplicación se puede copiar en varias instantáneas paralelas para lograr una alta disponibilidad. [2] Se pueden iniciar nuevos eventos en cualquier lugar, pero lo que es más importante, se pueden propagar a través de la red de almacenes de datos, actualizándolos a medida que llegan. Agregar nodos adicionales también se vuelve trivial: simplemente se puede tomar una copia del estado de la aplicación, alimentarla con un flujo de eventos y ejecutarla. [3]

La arquitectura basada en eventos puede complementar la arquitectura orientada a servicios (SOA) porque los servicios pueden activarse mediante disparadores que se activan ante eventos entrantes. [4] [5] Este paradigma es particularmente útil cuando el receptor no proporciona ningún ejecutivo autónomo [ aclarar ] .

SOA 2.0 lleva las implicaciones que brindan las arquitecturas SOA y EDA a un nivel más rico y sólido al aprovechar relaciones causales previamente desconocidas para formar un nuevo patrón de eventos. [ vago ] Este nuevo patrón de inteligencia empresarial desencadena un procesamiento humano o automatizado más autónomo que agrega valor exponencial a la empresa al inyectar información de valor agregado en el patrón reconocido que no se podría haber logrado anteriormente. [ vago ]

Topologías

La arquitectura basada en eventos tiene dos topologías principales: la “topología de intermediario”, en la que los componentes transmiten eventos a todo el sistema sin ningún orquestador. Proporciona el mayor rendimiento y escalabilidad. Mientras que en la “topología de mediador” hay un orquestador central que controla el flujo de trabajo de los eventos. Proporciona mejores capacidades de control y manejo de errores. También se puede utilizar un modelo híbrido y combinar estas dos topologías. [6]

Estructura del evento

Un evento puede estar formado por dos partes: el encabezado del evento y el cuerpo del evento. El encabezado del evento puede incluir información como el nombre del evento, la marca de tiempo del evento y el tipo de evento. El cuerpo del evento proporciona los detalles del cambio de estado detectado. El cuerpo del evento no debe confundirse con el patrón o la lógica que se puede aplicar como reacción a la ocurrencia del evento en sí.

Capas de flujo de eventos

Una arquitectura basada en eventos puede construirse sobre cuatro capas lógicas, comenzando con la detección de un evento (es decir, un estado o hecho temporal significativo), procediendo a la creación de su representación técnica en forma de una estructura de evento y terminando con un conjunto no vacío de reacciones a ese evento. [7]

Productor de eventos

La primera capa lógica es el productor de eventos, que detecta un hecho y lo representa como un mensaje de evento. Por ejemplo, un productor de eventos podría ser un cliente de correo electrónico, un sistema de comercio electrónico, un agente de monitoreo o algún tipo de sensor físico.

La conversión de los datos recopilados de un conjunto tan diverso de fuentes de datos en una única forma estandarizada de datos para su evaluación es una tarea importante en el diseño y la implementación de esta primera capa lógica. [7] Sin embargo, considerando que un evento es un marco fuertemente declarativo, cualquier operación informativa se puede aplicar fácilmente, eliminando así la necesidad de un alto nivel de estandarización. [ cita requerida ]

Canal de eventos

Esta es la segunda capa lógica. Un canal de eventos es un mecanismo de propagación de la información recopilada desde un generador de eventos al motor de eventos [7] o receptor. Puede ser una conexión TCP/IP o cualquier tipo de archivo de entrada (plano, formato XML, correo electrónico, etc.). Se pueden abrir varios canales de eventos al mismo tiempo. Por lo general, debido a que el motor de procesamiento de eventos debe procesarlos casi en tiempo real, los canales de eventos se leerán de forma asincrónica. Los eventos se almacenan en una cola, a la espera de ser procesados ​​más tarde por el motor de procesamiento de eventos.

Motor de procesamiento de eventos

El motor de procesamiento de eventos es la capa lógica responsable de identificar un evento y luego seleccionar y ejecutar la reacción adecuada. También puede activar una serie de afirmaciones. Por ejemplo, si el evento que llega al motor de procesamiento de eventos es un ID de producto bajo en stock, esto puede activar reacciones como “Solicitar ID de producto” y “Notificar al personal”. [7]

Actividad impulsada por eventos posteriores

Esta es la capa lógica donde se muestran las consecuencias del evento. Esto se puede hacer de muchas maneras y formas diferentes; por ejemplo, se envía un correo electrónico a alguien y una aplicación puede mostrar algún tipo de advertencia en la pantalla. [7] Dependiendo del nivel de automatización proporcionado por el receptor (motor de procesamiento de eventos), la actividad posterior podría no ser necesaria.

Estilos de procesamiento de eventos

Existen tres estilos generales de procesamiento de eventos: simple, de flujo y complejo. Los tres estilos suelen usarse juntos en una arquitectura madura basada en eventos. [7]

Procesamiento de eventos simple

El procesamiento de eventos simples se refiere a eventos que están directamente relacionados con cambios específicos y mensurables de condiciones. En el procesamiento de eventos simples, ocurre un evento notable que inicia acciones posteriores. El procesamiento de eventos simples se utiliza comúnmente para impulsar el flujo de trabajo en tiempo real, lo que reduce el tiempo de demora y los costos. [7]

Por ejemplo, se pueden generar eventos simples mediante un sensor que detecte cambios en la presión de los neumáticos o en la temperatura ambiente. La presión incorrecta de los neumáticos del automóvil generará un evento simple del sensor que activará una luz amarilla que avisará al conductor sobre el estado de un neumático.

Procesamiento de flujo de eventos

En el procesamiento de flujo de eventos (ESP), se producen tanto eventos ordinarios como notables. Los eventos ordinarios (órdenes, transmisiones RFID) se examinan para determinar su relevancia y se transmiten a los suscriptores de información. El procesamiento de flujo de eventos se utiliza comúnmente para impulsar el flujo de información en tiempo real dentro y alrededor de la empresa, lo que permite la toma de decisiones a tiempo. [7]

Procesamiento de eventos complejos

El procesamiento de eventos complejos (CEP) permite considerar patrones de eventos simples y ordinarios para inferir que ha ocurrido un evento complejo. El procesamiento de eventos complejos evalúa una confluencia de eventos y luego toma medidas. Los eventos (notables u ordinarios) pueden cruzar tipos de eventos y ocurrir durante un largo período de tiempo. La correlación de eventos puede ser causal, temporal o espacial. El CEP requiere el empleo de intérpretes de eventos sofisticados, definición y coincidencia de patrones de eventos y técnicas de correlación. El CEP se utiliza comúnmente para detectar y responder a anomalías, amenazas y oportunidades comerciales. [7]

Procesamiento de eventos en línea

El procesamiento de eventos en línea (OLEP) utiliza registros de eventos distribuidos asincrónicos para procesar eventos complejos y administrar datos persistentes. [8] OLEP permite componer de manera confiable eventos relacionados de un escenario complejo en sistemas heterogéneos. De este modo, permite patrones de distribución muy flexibles con alta escalabilidad y ofrece una gran consistencia. Sin embargo, no puede garantizar límites superiores en el tiempo de procesamiento.

Acoplamiento extremadamente suelto y bien distribuido

Una arquitectura basada en eventos está acoplada de manera extremadamente flexible y bien distribuida. La gran distribución de esta arquitectura existe porque un evento puede ser casi cualquier cosa y existir casi en cualquier lugar. La arquitectura está acoplada de manera extremadamente flexible porque el evento en sí mismo no conoce las consecuencias de su causa. Por ejemplo, si tenemos un sistema de alarma que registra información cuando se abre la puerta principal, la puerta en sí no sabe que el sistema de alarma agregará información cuando se abra la puerta, solo que la puerta se ha abierto. [7]

Acoplamiento semántico y más investigaciones

Las arquitecturas basadas en eventos tienen un acoplamiento débil en el espacio, el tiempo y la sincronización, lo que proporciona una infraestructura escalable para el intercambio de información y los flujos de trabajo distribuidos. Sin embargo, las arquitecturas de eventos están estrechamente acopladas, a través de suscripciones y patrones de eventos, a la semántica del esquema y los valores de los eventos subyacentes. El alto grado de heterogeneidad semántica de los eventos en implementaciones grandes y abiertas, como las ciudades inteligentes y la red de sensores, dificulta el desarrollo y el mantenimiento de sistemas basados ​​en eventos. Para abordar el acoplamiento semántico dentro de los sistemas basados ​​en eventos, el uso de la correspondencia semántica aproximada de eventos es un área activa de investigación. [9]

Implementaciones y ejemplos

Columpio de Java

La API de Java Swing se basa en una arquitectura basada en eventos. Esto funciona particularmente bien con la motivación detrás de Swing de proporcionar componentes y funcionalidades relacionadas con la interfaz de usuario. La API utiliza una convención de nomenclatura (por ejemplo, "ActionListener" y "ActionEvent") para relacionar y organizar las cuestiones relacionadas con los eventos. Una clase que necesita estar al tanto de un evento en particular simplemente implementa el detector apropiado, anula los métodos heredados y luego se agrega al objeto que activa el evento. Un ejemplo muy simple podría ser:

clase pública FooPanel extiende JPanel implementa ActionListener { público FooPanel () { super ();            JButton btn = new JButton ( "¡Haz clic en !" ); btn.addActionListener ( this ) ;      esto . agregar ( btn ); }  @Override public void actionPerformed ( ActionEvent ae ) { System . println ( " ¡ Se ha hecho clic en el botón!" ) ; } }       

Otra opción de implementación es agregar el detector al objeto como una clase anónima y, de esta manera, utilizar la notación lambda (desde Java 1.8). A continuación, se muestra un ejemplo.

clase pública FooPanel extiende JPanel { pública FooPanel () { super ();          JButton btn = new JButton ( "¡Haz clic en mí!" ) ; btn.addActionListener ( ae - > System.out.println ( " ¡ Se ha hecho clic en el botón!" ) ) ; this.add ( btn ) ; } }         

JavaScript

(() => { 'utilizar estricto' ;    clase EventEmitter { constructor () { this.events = new Map ( ) ; }          on ( evento , oyente ) { if ( typeof oyente !== 'función' ) { throw new TypeError ( 'El oyente debe ser una función' ); } let oyentes = this . events . get ( evento ); if ( ! oyentes ) { oyentes = new Set (); this . events . set ( evento , oyentes ); } oyentes . add ( oyente ); return this ; }                                off ( evento , oyente ) { if ( ! argumentos . longitud ) { this . eventos . borrar (); } else if ( argumentos . longitud === 1 ) { this . eventos . eliminar ( evento ); } else { const oyentes = this . eventos . obtener ( evento ); if ( oyentes ) { oyentes . eliminar ( oyente ); } } return this ; }                               emitir ( evento , ... argumentos ) { const oyentes = this . eventos . obtener ( evento ); si ( oyentes ) { para ( dejar oyente de oyentes ) { oyente . aplicar ( this , argumentos ); } } devolver this ; } }                        este .EventEmitter = EventEmitter ; })() ;  

Uso:

const events = new EventEmitter (); events . on ( 'foo' , () => { console . log ( 'foo' ); }); events . emit ( 'foo' ); // Imprime "foo" events . off ( 'foo' ); events . emit ( 'foo' ); // No pasará nada           

Objeto Pascal

Los eventos son uno de los elementos fundamentales del lenguaje Object Pascal . Aquí se utiliza el modelo unidifusión (uno a uno), es decir, el emisor envía información a un solo destinatario. Esta limitación tiene la ventaja de que no necesita un detector de eventos especial. El evento en sí es un puntero a un método en otro objeto. Si el puntero no está vacío, cuando se produce un evento, se llama al controlador de eventos. Los eventos se utilizan habitualmente en clases que admiten GUI. Sin embargo, esta no es la única área de aplicación de los eventos. El siguiente código es un ejemplo de uso de eventos:

unidad MyCustomClass ; interfazusa Clases ; tipo {definición de su propio evento} TAccidentEvent = procedimiento ( Sender : TObject ; const AValue : Integer ) de objeto ;             TMyCustomObject = class ( TObject ) private FData : Integer ; // un ejemplo de un campo simple en una clase FOnAccident : TAccidentEvent ; // evento: referencia a un método en algún objeto FOnChange : TNotifyEvent ; // evento: referencia a un método en algún objeto procedure SetData ( Value : Integer ) ; // un método que establece el valor de un campo en la clase protected procedure DoAccident ( const AValue : Integer ) ; virtual ; // un método que genera un evento basado en su propia definición procedure DoChange ; // un método que genera un evento basado en una definición de la biblioteca VCL public constructor Create ; virtual ; // constructor de la clase destructor Destroy ; override ; // destructor de la clase published property Data : TAccidentEvent read FData write SetData ; // declaración de una propiedad en una clase property OnAccident : TAccidentEvent read FOnAccident write FOnAccident ; // exponiendo el evento fuera de la clase property OnChange : TNotifyEvent read FOnChange write FOnChange ; // exponiendo el evento fuera de la clase procedure MultiplyBy ( const AValue : Integer ) ; // un método que usa su propia definición del evento end ; implementation                                                                   constructor TMyCustomObject . Crear ; comenzar FData : = 0 ; fin ;    destructor TMyCustomObject . Destruir ; inicio FData := 0 ; heredado Destruir ; fin ;      procedimiento TMyCustomObject . DoAccident ( const AValue : Integer ) ; comenzar si Assigned ( FOnAccident ) entonces FOnAccident ( Self , AValue ) ; fin ;        procedimiento TMyCustomObject . DoChange ; comenzar si Asignado ( FOnChange ) entonces FOnChange ( Self ) ; fin ;     procedimiento TMyCustomObject . Multiplicar por ( const AValue : entero ) ; comenzar FData := FData * AValue ; si FData > 1000000 entonces DoAccident ( FData ) ; fin ;              procedimiento TMyCustomObject . SetData ( Valor : Entero ) ; comenzar si FData <> Valor entonces comenzar FData := Valor ; DoChange ; fin ; fin .             

La clase creada se puede utilizar de la siguiente manera:

... procedimiento TMyForm . ShowCustomInfo ( Sender : TObject ) ; comienza si Sender es TMyCustomObject entonces ShowMessage ( 'Los datos han cambiado.' ) ; fin ;        procedimiento TMyForm . PerformAcident ( Sender : TObject ; const AValue : Integer ) ; begin si Sender es TMyCustomObject then ShowMessage ( '¡Los datos han excedido 1000000! El nuevo valor es: ' + AValue . ToString ) ; end ; ... {declarar una variable que es un objeto de la clase especificada} var LMyObject : TMyCustomObject ; ... {creación del objeto} LMyObject := TMyCustomObject . Create ; ... {asignar un método a un evento} LMyObject . OnChange := MyForm . ShowCustomInfo ; LMyObject . OnAccident := MyForm . PerformAcident ; ... {eliminar un objeto cuando ya no es necesario} LMyObject . Free ; ...                       

Desafíos

Uno de los desafíos de utilizar una arquitectura basada en eventos es el manejo de errores. Una forma de abordar este problema es utilizar un procesador de manejo de errores independiente. De este modo, cuando el consumidor de eventos experimenta un error, envía de forma inmediata y asincrónica el evento erróneo al procesador de manejo de errores y continúa. El procesador de manejo de errores intenta corregir el error y envía el evento de vuelta al canal original. Pero si el procesador de manejo de errores falla, puede enviar el evento erróneo a un administrador para que lo inspeccione más a fondo. Tenga en cuenta que si utiliza un procesador de manejo de errores, los eventos erróneos se procesarán fuera de secuencia cuando se vuelvan a enviar. [6]

Otro desafío de usar una arquitectura basada en eventos es la pérdida de datos. Si alguno de los componentes falla antes de procesar y transferir con éxito el evento a su siguiente componente, entonces el evento se descarta y nunca llega al destino final. Para minimizar la posibilidad de pérdida de datos, puede conservar los eventos en tránsito y eliminarlos o sacarlos de la cola solo cuando el siguiente componente haya confirmado la recepción del evento. Estas funciones se conocen generalmente como "modo de confirmación del cliente" y "soporte del último participante". [6]

Véase también

Artículos

Referencias

  1. ^ K. Mani Chandy Aplicaciones basadas en eventos: costos, beneficios y enfoques de diseño, Instituto Tecnológico de California , 2006
  2. ^ Martin Fowler, Event Sourcing, diciembre de 2005
  3. ^ Martin Fowler, Modelo paralelo, diciembre de 2005
  4. ^ Hanson, Jeff (31 de enero de 2005). "Servicios basados ​​en eventos en SOA". JavaWorld . Consultado el 21 de julio de 2020 .
  5. ^ Sliwa, Carol (12 de mayo de 2003). "Arquitectura basada en eventos preparada para una amplia adopción". Computerworld . Consultado el 21 de julio de 2020 .
  6. ^ abc Richards, Mark. Fundamentos de la arquitectura de software: un enfoque de ingeniería . O'Reilly Media. ISBN 978-1492043454.
  7. ^ abcdefghij Brenda M. Michelson, Descripción general de la arquitectura basada en eventos, Patricia Seybold Group , 2 de febrero de 2006
  8. ^ "Procesamiento de eventos en línea - Cola ACM". queue.acm.org . Consultado el 30 de mayo de 2019 .
  9. ^ Hasan, Souleiman, Sean O'Riain y Edward Curry. 2012. “Coincidencia semántica aproximada de eventos heterogéneos”. En la 6.ª Conferencia internacional de la ACM sobre sistemas distribuidos basados ​​en eventos (DEBS 2012), 252–263. Berlín, Alemania: ACM. “DOI”.

Enlaces externos