Desde hace años, una parte importante de nuestros servicios de middleware se basa en la integración de sistemas con Enterprise ServiceBus (ESB), especialmente con los proyectos Apache ServiceMix y JBoss Fuse.
Como otra alternativa en las integraciones empresariales, las arquitecturas dirigidas por eventos (EDA) están tomando un gran protagonismo hasta el punto que existen artículos que consideran incluso que los motores ESB están obsoletos y por este motivo, llevamos un tiempo considerable evaluando Apache Kafka y la plataforma Confluent (versión empresarial de Apache Kafka).
Tras leer el artículo y la presentación en Slideshare del evangelista tecnológico de Confluent Kai Wähner en los que plantea las arquitecturas EDA como la mejor alternativa en el ámbito de las integraciones, dejo en este artículo una reflexión sobre las arquitecturas dirigida por eventos (EDA) y los motores Enterprise ServiceBus (ESB) que conducen a conclusiones bien diferentes.
Integración con ESB: El repartidor se encarga de recoger el pedido directamente del vendedor y lo entrega al comprador en mano
Este caso es una situación muy habitual en la vida real: Supongamos que realizamos un pedido por teléfono a la pizzería, el propietario del establecimiento prepara la pizza y una vez horneada, el repartidor la recoge, arranca la moto, zigzaguea entre las calles de la ciudad y nos la entrega en la puerta de nuestro domicilio.
El vendedor se encarga exclusivamente de confeccionar la pizza, el comprador se la comerá y el repartidor es el responsable de llevar el pedido de origen a destino.
Traducido en el ámbito del software, diríamos que el sistema origen (vendedor) produce un mensaje (pizza), el sistema destino (comprador) consume el mensaje (pizza) y es exclusivamente el agente integrador (repartidor) quien se encarga de llevar el mensaje de origen a destino.
A la hora de abordar la integración de esta forma, esta idea desencadena las siguientes conclusiones :
- El sistema origen sólo tiene código para generar el mensaje.
- El sistema destino sólo tiene código para consumir el mensaje.
- El agente integrado tiene código para leer el mensaje del sistema origen, enrutar y transformar el mensaje entre ambos extremos y escribir el mensaje en el sistema destino.
Aunque no parezca especialmente trascendente, pensad que este corte permite que origen y destino estén aislados, es decir que los equipos de desarrollo de cada parte no necesita saber nada del otro y se concentran exclusivamente a su labor (producir o consumir el mensaje) lo que facilita la confección de software. De forma complementaria, existirá un equipo de desarrollo que programará la lógica de enrutamiento y transformación del dato de origen a destino, el cual si deberá conocer ambos extremos.
Proyectos como Apache ServiceMix, Talend y JBoss Fuse implementan un motor ESB, los cuales fundamentan parte de su arquitectura en la tecnología OSGI (Apache Karaf) y una implementación de los patrones EIP a través de Apache Camel, el cual contiene además componentes para automatizar los procesos de lectura en origen y escritura en destino.
Estos proyectos aportan por lo tanto lógica de enrutamiento del mensaje y conectores de escritura de lectura / escritura (ficheros, SFTP, AS400, Amazon AWS, …) para facilitar que el agente integrador tenga la mayor parte del código ya implementado.
Este principio permite centrar las integraciones en un punto determinado para huir de las integraciones ‘spaguetti’ en las que el código que une los extremos se encuentra repartido en todos los puntos del camino.
Como vemos, utilizar un repartidor es especialmente útil cuando el vendedor se desentiende del reparto y el comprador no puede ir a buscar el pedido. Es decir, este planteamiento es adecuado en integraciones con sistemas que no pueden ni trasladar ni transformar el mensaje, arquitecturas dónde se quiere centralizar la lógica de integración de múltiples sistemas o ya se disponga de un componente de lectura / escritura.
Integración con EDA: El vendedor deposita el pedido en un punto de recogida y el comprador lo recoge de ahí.
Este caso también es muy común en nuestro día a día: Supongamos que el vendedor prepara la pizza y se encarga personalmente de depositarla en un punto de encuentro mientras que el comprador acude a este lugar y recoge el pedido.
El vendedor se encarga de confeccionar y depositar la pizza en un punto de encuentro mientras que el comprador acude a este lugar a recogerla.
Traducido en el ámbito del software, diríamos que el sistema origen (vendedor) escribe un mensaje (pizza) en un buzón y el sistema destino (comprador) lee el mensaje (pizza) del buzón que estaba escuchando.
A la hora de integrar, esta idea conduce a las siguientes conclusiones:
- El sistema origen tiene código para generar el mensaje y escribirlo en el buzón.
- El sistema destino tiene código para leer el mensaje del buzón y consumirlo.
La problemática de la integración se aborda de forma diferente al caso 1 (en el que existía un agente integrador que se encargaba de trasladar / transformar el dato) ya que ahora el sistema origen se encarga también de trasladar ‘parcialmente’ el mensaje producido (escribirlo en un buzón) y el sistema destino también se encarga de ‘trasladarse’ para consumir el mensaje (leerlo del buzón).
Uno de los proyectos más relevantes es el proyecto Apache Kafka y la plataforma Confluent (versión empresarial), que incluye además de soporte directo del fabricante una serie de proyectos complementarios a la hora de realizar integraciones. Como punto a destacar, es importante tener en cuenta que nos encontramos con un sistema de mensajería asíncrono escalable en entornos de alta disponibilidad.
Estos proyectos aportan librerías SDK en diferentes lenguajes de programación para que los sistemas origen y destino puedan escribir / leer el mensaje en los buzones del sistema de mensajería asíncrono.
Obviamente, prescindir del repartidor es especialmente interesante cuando el vendedor y el comprador puede asumir la entrega y recepción del pedido por ellos mismos. Es decir, este planteamiento es especialmente útil en integraciones con sistemas que sí pueden asumir la escritura y lectura del mensaje en un sistema de mensajería asíncrono.
Conclusiones
Pues según las circunstancias, ambos enfoques pueden ser útiles e incluso pueden convivir entre ellos.
Usaría un motor ESB:
- Cuando los sistemas origen y destino son pasivos, es decir que no puede enganchar por sí mismos con nada (sistemas legacy).
- Cuando tenemos equipos de desarrollo especializado sólo en un sistema específico y no queremos / podemos que conozcan la tecnología de otros sistemas.
- Cuando queremos que existan equipos de desarrollo exclusivamente especializados en la integración, es decir llevar el dato convertido de origen a destino.
- Cuando la lógica de lectura del mensaje en el sistema origen y la de escritura del mensaje en el sistema destino ya exista entre los componentes ofrecidos en el motor (Apache Camel en el caso de Apache ServiceMix / JBoss Fuse).
- Cuando no queremos que la lógica de integración esté repartida anárquicamente en diferentes orígenes y destinos, y que esté centralizada en un punto común.
Usaría una arquitectura EDA:
- Cuando los sistemas origen y destino no son pasivos, es decir que disponen de herramientas / librerías para trabajar contra sistemas de mensajería asíncrona.
- Cuando es más ágil pactar el mensaje a compartir en EDA que hacer una integración en ESB.
- Cuando el volumen de datos a consumir / producir alcanza umbrales muy elevados.
Espero haber ayudado o cuanto menos, abrir debate al respecto. ¡Saludos!
0 comentarios