Sitemap
IngenioDS

Iniuriarum iter aliena, extremis malis extrema remedia

EDA: Estrategia de sistemas comunicados por eventos

--

Post relacionados:
EDA: ¿Qúe es?
EDA: implementación básica

Los microservicios aceleran el desarrollo y permiten a las empresas innovar más rápido y mantenerse al día en tiempos donde la información y su tratamiento es oro, conociendo los pros y contras que dicha arquitectura representa considero que el desafío más importante al que me he enfrentado hasta este momento es la gestión de datos distribuidos. Desde la óptica donde cada sistema (y muy posible dentro del sistema cada microservicio) tiene su propia base de datos privada. Es difícil implementar transacciones que mantengan la coherencia de los datos en varios servicios, así como lograr la consistencia en consultas que recuperan datos de varios servicios; y en la mayoría de escenarios las transacciones suceden de manera independiente y completamente desacoplada dentro de cada sistema.

Hay que tener en cuenta que no todos los sistemas van a responder a las mismas necesidades y prioridades, fue determinante hacer un ejercicio con teorema CAP y conocer qué aristas eran las más importantes para definir el tipo de arquitectura a implementar. El teorema es altamente utilizado en la escogencia de bases de datos pero al extrapolarlo a otras áreas nos brinda claridad con respecto a dónde centrar los primeros esfuerzos.

Las arquitecturas orientadas por eventos tienen tres componentes clave: productores de eventos, enrutadores de eventos y consumidores de eventos. Un productor publica un evento en el enrutador, que filtra y envía los eventos a los consumidores. Los servicios productores y los servicios consumidores están desacoplados, lo que permite escalarlos, actualizarlos e implementarlos de forma independiente. [What is an Event-Driven Architecture?, Amazon AWS]

Dentro de la solución planteada no llevamos a cabalidad una arquitectura orientada por eventos pero si tomamos ciertos aspectos que solucionaron nuestra necesidad primaria.

  • Mantener la información limpia.
  • Identificación y tratamiento de errores.
  • Identificación de transacciones y registros de las mismas.
  • Estabilidad del sistema.

Componentes principales

El sistema está compuesto por tres componentes principales (1) sistema externo donde tenemos que consultar información y ejecutar comandos por medio de peticiones REST, (2) sistema interno donde manejamos la lógica de la aplicación y (3) sistema legado donde convergen todos los procesos de la compañía.

Consideraciones

El sistema externo puede traer un número entre cero y treinta mil registros (es el número más alto registrado pero no hay un límite para ello) por cada petición.

El sistema core debe ser capaz de procesar dicha cantidad de registros pero dentro de su procesamiento intervienen otros softwares tanto a nivel de validaciones como a nivel de integración con el sistema legado.

Componentes secundarios

Dentro del sistema tenemos tres componentes secundarios (1) proxy que se encarga de comunicar con el sistema externo, (2) middleware que se encarga de comunicar con el sistema legado y (3) frontend para visualizar y relanzar eventos de error.

Componente de apoyo

Identificamos dos componentes de apoyo (1) backoffice es el encargado de escuchar los eventos tanto de error como los procesados y por otro lado tenemos a (2) el exchange de mensajes (pubsub de gcp) que pese a no ser un componente implementado inhouse es el componente enrutador.

Nota: El middleware y el sistema legado no se visualizan porque no hacen parte directa del manejo de eventos.

Diagrama de componentes

Press enter or click to view image in full size

Anatomía de un evento

Get Gomez M’s stories in your inbox

Join Medium for free to get updates from this writer.

Los eventos dentro de su composición comprenden tres partes fundamentales un campo que nos permita su identificación, un campo que nos permita tener información del contexto y la información relacionada con la naturaleza del evento. adicional a estos campos los eventos de error contienen un campo que nos permite identificar cuáles fueron los errores que ocurrieron dentro del procesamiento de dicho evento.

Press enter or click to view image in full size
  • id: identificación del evento es un UUID generado por el.
  • data: es un JSon escapado con la información concerniente a la operación de negocio.
  • headers: esta es información de contexto que en este caso se limita a la fecha en la que el evento es registrado, el sistema que lo registra, el tipo del evento y el id de la transacción asociada al evento.

Nota: la forma de la información así como los headers de la misma ya dependen de cada implementación y así como no es camisa de fuerza tener los headers aquí señalados, si es recomendable identificar el tipo y la fecha asociada al evento.

La información concerniente a un error se almacena en:

Press enter or click to view image in full size

El header ERROR que indica si es un error de forma o de negocio y la lista errors donde referenciamos el error con un id (para buscarlo en los logs si es necesario), un código que viene directamente señalado en las excepciones propias del sistema y un mensaje amigable al usuario que brinde información adicional.

Nota: la estructura de los errores es la propuesta que nos dio valor, no es camisa de fuerza pero se recomienda la tipificación y una estrategia de trazabilidad de los mismos.

Transacciones

A este punto conocemos como son los errores y cuales son los componentes que intervienen en el sistema pero aun nos falta describir cómo interactúan entre ellos para lograr minimizar el tiempo de respuesta y la carga operativa que conlleva este manejo de errores.

Las transacciones son el centro de todo este juego de identificación y traza de eventos, y relanzamiento de errores.

En nuestro caso las transacciones inician desde el componente back-office, las mismas tienen un ID, una fecha y un tipo. Las transacciones pueden ser creadas desde una petición REST a demanda del usuario o por la ejecución de una tarea programada.

Analizaremos inicialmente la transacción que está relacionada a una tarea programada (1) al momento de nacer se genera un UUID y este es (2) enviado al componente proxy que ejecuta la petición al sistema externo (la respuesta al sistema externo puede contener desde cero a muchos registros cada uno de estos registros es tratado de manera individual), (3) analizado en su forma para descartar que al sistema core no le llegue información corrupta y (4) en caso de detectar errores de forma los mismos son enviados a la DLQ desde el componente proxy en forma de eventos de error de forma. Los registros que cumplan con las validaciones de forma (5) son transformados a un formato que el componente core es capaz de entender (lenguaje de dominio interno) y (6) son enviados en forma de eventos al enrutador (exchange de mensajes) donde por medio de reglas se envían a sus correspondientes colas de mensajes, (7) los mensajes son escuchados por el componente core donde se identifica cuál es el tipo de evento y (8) se llama a un listener apropiado para el procesamiento del mismo, la primera etapa de ese procesamiento son las (9) validaciones de negocio en caso que cumpla con todas las validaciones el mensaje es almacenado en los repositorios correspondientes así como se notifica la aceptación del mensaje, en caso que las validaciones no se cumplan (10) los errores son lanzados como una lista de excepciones las cuales son capturadas por el listener y enviadas a las DLQ como un evento de error.

Tanto los eventos de error como los procesados son escuchados por el back-office el cual se encarga de mantenerlos en los repositorios y asociarlos a la transacción correspondiente.

Press enter or click to view image in full size

En este punto tenemos una transacción asociada a un listado de eventos de error ya sea de forma o negocio y a un listado de eventos procesados correctamente.

Relanzamiento de errores

El relanzamiento de errores es una transacción donde a diferencia de la ejecución donde se comunica con el componente externo, en esta parte del proceso interviene el frontend en una pantalla de visualización de errores.

Press enter or click to view image in full size

Donde el usuario puede consultar y seleccionar los errores. Actualmente por restricción funcional solo se relanzan errores de negocio.

Press enter or click to view image in full size

Al realizar la operación de relanzamiento, los errores seleccionados se convierten en los eventos asociados a una nueva transacción y son escritos directamente en el enrutador que está escuchando el componente core reiniciando el ciclo del listener asociado a dicho tipo de evento.

Press enter or click to view image in full size

Al final tenemos una transacción y los eventos asociados a la misma.

No necesariamente esta estrategia sea funcional en todos los proyectos pero nos ha funcionado en varios proyectos de manera limpia.

--

--

Gomez M
Gomez M

Written by Gomez M

Padre, Hijo, Hermano, Humano

IngenioDS
IngenioDS

Published in IngenioDS

Iniuriarum iter aliena, extremis malis extrema remedia