Personalmente tuve la fortuna de estar presente en el último evento de AWS re:invent 2022, y una de las cosas que más me gustó fué la Keynote del Dr. Werner Vogels. Es cierto que este es uno de los momentos más esperados del evento, y uno de los favoritos de muchos... entre los que me incluyo...
The World is Asynchronous
Pero la particularidad de esta Keynote, para mí, es que en un tiempo en que se resaltan los diferentes avances de la Inteligencia Artificial, o las Economías Desentralizadas con la Blockchain... El mensaje del Dr. Vogel en su Keynote fué como "volver a las bases" e inaugurar un nuevo tiempo, o un nuevo ciclo: en pleno 2022, afirmando que "The World is Asynchronous" y marcando el resurgimiento de las EDA: las Event-Driven Architectures
Y cuando pensamos en el "Asincronismo" y las "Arquitecturas Orientadas a Eventos" no solamente visualizamos a los a los microservicios y sus orquestaciones, o a las SOA, sino que fácilmente podemos seguir retrocediendo a más de 20 años atrás cuando en los líbros de Arquitectura de Software nos presentaban a patrones para desacoplar como el de "Publicación/Subscripción"
Patrones de Comunicación en nuestro mundo
A veces me gusta pensar en nuestro patrón de comunicación como personas, que, cuando hablamos, además de comunicarnos con la persona a la que nos estamos dirigiendo, también están todos los que nos escuchan. Y que depende de cada persona capaz de recibir al mensaje, el "prestar atención" o "suscribirse", incluso alguien que podríamos no querer que participe de la comunicación...
Ese modelo de comunicación de "publisher and subscriber", como refuerza Werner Vogels, es el predominante en nuestro mundo asyncrónico...
Dilemas de Comunicación en el mundo de EDA
Pero ¿Cómo implementar la comunicación en un EDA?
Es decir, ¿Que decisiones de diseño debemos tomar?. A la hora de publicar un evento, ¿En dónde lo publico?¿En ún único Event-Bus para todo el sistema al que todos están suscriptos?¿O en diferentes Event-Bus con alguna identidad funcional o técnica que solamente algunos servicios se suscriben?¿Cómo se define el límite de cada identidad funcional?, que seguramente, a medida que el sistema crezca se puede ir tornando más difuso..
Y la siguiente pregunta derivada, sería: ¿Que reglas debería establecer para gobernar a ese modelo de comunicación asyncrónica? Y ahí podemos estar en el dilema de elegir entre dos grandes aproximaciones para la comunicación entre (micro)servicios: la Orquestación y la Coreografía que vamos a repasar a continuación:
Orquestación vs Coreografía
Supongamos que en nuestro sistema cada (micro)servicio tiene su propia base datos y necesitamos un mecanismo para lograr la consistenacia entre las distintas báses de datos cuando en el sistema se realiza una transacción, que por definición, debe verse reflejada de forma completa en todos los (micro)servicios, o en su defecto, se cancelada o revierte para evitar problemas de inconsitencia.
En la aproximación de "orquestación" hay un servicio dedicado, como un director de orquesta, que dirige cómo debería cada servicio actualizar su estado.
En la aproximación de "coreografía", no existe la figura de un director, pero todos los servicios conocen cómo deben _actualizar _a su estado interno al recibir el evento, de, por ejemplo, la ejecución de una transacción.
Dicho sea de paso, estas son dos posibles aproximaciones del patrón SAGA para micro servicios, y están muy bien explicados en el sitio de "Microservice Architecture" de Chris Richardson
¿Cómo implementar un EDA?
Y en este punto, me gustaría compartir mi experiencia en la implementación de un EDA en un entorno académico, con la consigna de coordinar la integración de ocho módulos autónomos con su propio medio de persistencia.
A simple vista, un diagrama similar al siguiente:
Y se aplicaron las siguientes decisiones de diseño:
Primero, la comunicación se realizó a través de un componente centralizado "EDA" que implementaba el patrón de "Publisher and Subscriber"
Segundo, para la lógica de negocio que implicaba transaccionalidad entre distintos módulos, se seleccionó una estrategia "coreográfica": es decir, la lógica de coordinación para ejecutar una transacción no está centralizada en un componente director, sino que cada interviniente de la transacción conoce de qué manera deber actualizar a su estado interno ante la llegada del evento de la transacción.
En este punto, entedimos que se reducía el acoplamiento al no depender de un componente centralizado y que se fortalezca la independencia entre los módulos al actuar siguiendo la filosofía de coreografía.
También, en este punto, entendimos que el sistema escalaba mejor, porque en el caso que un nuevo módulo se incorpore al sistema, podría integrarse sin afectar a los demás e implementando su lógica de comportamiento en la coreografía, al estar cada componente actual y nuevo debilmente acoplado al sistema.
Tercero, la publicación de mensajes: para reducir al acoplamiento aún mas entre los módulos, se mantuvo la decision que cada cómponente publique sus mensajes y eventos en un tópico propio. Es decir, lo que un componente tiene que notificar hacia el resto de los sistemas, lo deja publicado en su propio tópico y no es su responsabilidad enviarle ese mensaje a otro módulo que esté interesado o necesitando recibirlo. Es responsabilidad del módulo que necesita a los mensajes suscribirse a los tópicos de cada uno de los emisores con los que necesita interactuar.
La responsabilidad de un emisor, por ejemplo, la aplicación call-center, es solo de publicar sus mensajes en él topico que lleva su nombre "call-center". Luego, el módulo que necesite, por ejemplo, reportar un ticket, o conocer su resolución, será el que se suscriba al tópio "call-center"Esa decición reduce el acoplamiento, y permite que si, por ejemplo, se incorpora un nuevo módulo de analítica de reclamos simplemente se incorpora como nuevo módulo al sistema y se suscribe al tópico de "call-center" para hacer su lógica y generar sus resultados. Y el resto de los módulos no se vieron afectados por su incorporación.
En esta aproximación, con estos tres pilares para organizar la comunicación entre los servicios de una arquitectura orientada a eventos, con decisiones de integración de componentes que favorecen el desacoplamiento (ej, elegir coreografía como medio de transaccionalidad entre servicios, y publicar los mensajes en solo el canal del propio módulo) llevó el proyecto a feliz término y permitió la integración del ecósitema de los módulos demostrando que las decisiones de diseño que se tomaron hacen posible la implamentación de una EDA sin incrementar la complejidad en la forma de comunicación de los servicios que integra.
Bueno, espero que nuestra experiencia a través de un ejercicio académico de integración en un arquitectura orientada a eventos, puede ser como referencia para identificar a un camino exitos, aunque segurametne existen otras alternativas de hacer las cosas de forma más eficiente.
Muchos éxitos!
Pablo
Top comments (4)
Me parece increíble esta arquitectura, es lo que pienso implementar para un SaaS pero no tenía claro el "cómo" dado que no todos los (micro)servicios tendrían que estar activos todo el tiempo. ¿Me recomendaría algo (contenido o consejos) para comenzar a construir un MVP bajo este modelo?
Hola Christian, buen día!
En el artículo está con cierta relación con AWS por la intro :), y en AWS, el servicio Amazon EventBridge es el más interesante para empezar con un EDA basado en un Bus de Eventos (un publicador y varios subscriptores).
Otra aproximación es con AWS SQS (colas y tópicos que sirven para desacoplar) más orientado a productor-consumidor, y para tener los mensajes dirigidos hacia varios suscriptores hay que implementar una arquitectura de fan-out combinando SNS con SQS...
Pero para tratar de hacer un MVP de integraciones de un SaaS con un EDA, lo mejor y lo más completo es que le puedas dar un vistazo al servicio de Amazon EventBridge y para eso el link ofical parece bastante claro: "How to Use Amazon EventBridge to Build Decoupled, Event-Driven Architectures"
Otra forma fácil para un MVP fuera de AWS es con RabbitMQ directamente como el broker de mensajería... y después tendrías que revisar cómo desplegarlo en un entorno en línea.
Bueno, muchos éxitos!!
Excelente articulo, en la plataformas que creamos en la empresa usamos natsio y su coreografia entre microservicios, acoplamiento de nuevas fixtures es una hermosura, en caso de fallas sabes donde ir y ejecutar la accion correspondiente, utlizamos paquetes de subscripcion donde damos aviso al resto de micros que se subscriben. La verdad es una obra de arte cuando te encuentras con la coreografia de mil microservicios funcionand entre si! Saludos desde Argentina - Mendoza
Que bueno! gracias por el comentario!! Si, la verdad está muy bueno cuando todo funciona... parce mágica la reacción a los eventos en todo el ecositema... aca el caso fue desarrollado organizado en nueve scrums, dedicados a cada uno de los ocho servicios y el core y salío muy bien... che, que lindo Mendoza... muchos éxitos! :)