Los Middlewares de mensajes (MOM)
Introducción
Los Middleware de mensajes, Message-Oriented Middleware en inglés, o su abreviatura MOM, es un software que intercambia información con mensajes a través de una red informática. Esto permite tener un acoplamiento débil y asíncrono a través del almacenamiento de mensajes a la espera de ser procesados. Los mensajes se componen de una parte técnica utilizada por la parte middleware y una parte de datos, cuyo formato queda a discreción de las aplicaciones que utilizan estos mensajes.
También hablamos de Brokers y servidores de mensajes.
Existen dos familias principales:
-
Los mensajes pueden ser enrutados, enriquecidos, empobrecidos, acoplados, transformados por el middleware, como para los servicios web, a menudo denominados integración de aplicaciones empresariales o abreviado como EAI (Enterprise Application Integration en inglés). En este caso, el middleware se utiliza para permitir el intercambio de información entre aplicaciones heterogéneas con tendencias monolíticas.
-
Los mensajes simplemente se transportan (y almacenan temporalmente) sin modificaciones. A estos se les llama mensajes pobres.
Al igual que sucede con los servicios web, que suelen ser síncronos, la tendencia es utilizar mensajes pobres y no poner reglas de negocio en la gestión de mensajes. Hay una excepción a esta regla, como veremos en este capítulo....
Implementaciones open source
Protocolo |
Nombre del proveedor |
ActiveMQ |
Apache Software Foundation |
HornetMQ |
JBoss |
JBoss Messaging |
JBoss |
Kafka |
Apache Software Foundation |
RabbitMQ |
AMQP |
ZeroMQ |
Imatix |
Estas implementaciones son gratuitas, pero el soporte y las adaptaciones se deben hacer internamente y, si encuentra un problema, debe gestionarlo. Son sencillas en cuanto al desarrollo, pero se pueden convertir rápidamente en un infierno durante la producción y el balanceo de carga. Por este motivo, las empresas se ofrecen a ayudar mejorando las implementaciones y ofreciendo soporte a nivel del desarrollador y la puesta en producción. Incluso es posible personalizar la implementación para adaptarla a las necesidades del cliente, optimizando ciertos aspectos en función del uso. Una breve intervención de un experto en el producto, aunque a menudo se percibe como costosa, generalmente ahorra un tiempo considerable y anticipa problemas.
Un experto explicará, por ejemplo, el mecanismo de los retry que requieren tener sistemas idempotentes en caso de timeout, dando como resultado un retry con todo lo que implica. No es suficiente ver vídeos de kárate para tener un cinturón negro en kárate. No basta con seguir un tutorial para elegir una arquitectura empresarial, cuya implementación durará años. Hay que practicar, formarse, consultar a expertos y experimentar.
Implementaciones propietarias
Protocolo |
Nombre del proveedor |
IBM WebSphere MQ |
IBM |
MSMQ |
Tibco Software |
TIBCO Rendezvous |
JBoss |
Synchrony Messaging |
Axway |
A menudo, estas implementaciones se combinan con otras herramientas en un conjunto coherente. Con frecuencia son costosas, pero hay soporte y garantías. También proporcionan soluciones listas para usar y, algunas veces, están muy bien adaptadas a ciertos contextos.
Casos de uso
Hoy en día, existen multitud de protocolos y API, como JMS, Stomp, MQTT, AMQP, XMPP, etc., y herramientas basadas en mensajes, como Flume, Logstash, Syslog, etc.
En este capítulo, veremos algunos ejemplos de uso con Spring para ActiveMQ (JMS), Redis y RabbitMQ para un uso puro MOM abordando el contexto de uso.
ActiveMQ es la respuesta por defecto para hacer MOM. Las herramientas Kafka y RabbitMG tienen diferentes patterns de arquitectura para abordar los problemas de envío y recepción de mensajes.
Para el desarrollo, debemos elegir la implementación en función del contexto de uso. Algunas veces aún no conocemos todas las limitaciones futuras y no sabemos cómo evolucionará la aplicación. Por lo tanto, es necesario separar en el código la implementación de la entrega y el consumo de los mensajes del código de negocio, para que sea relativamente fácil cambiar de MOM. Este es el enfoque de la arquitectura hexagonal. Para la parte técnica del código, nos adaptamos lo mejor posible al MOM utilizado y Spring ofrece mucha ayuda en este punto con sus capas de abstracción.
De hecho, migraremos la aplicación para tener en cuenta las preocupaciones más importantes:
-
facilidad de uso a nivel de codificación,
-
facilidad para las pruebas,
-
escalado (scaling) horizontal y vertical,
-
seguridad de funcionamiento (tiempo de inactividad, recuperación...
JMS y ActiveMQ
JMS (Java Messaging Service) es una interfaz de programación que permite intercambiar mensajes de forma asíncrona (y menos habitualmente de manera síncrona en modo punto a punto) entre aplicaciones Java.
Todos los servidores Jakarta EE proporcionan un servicio JMS vinculado a JCA (Java Connector Architecture).
JMS se basa en un middleware para la implementación.
Históricamente, hay varias versiones de JMS:
Versiones |
Fechas |
Adds |
1.0.2b |
Junio de 2001 |
|
1.1 |
Marzo de 2002 |
|
2.0 |
Marzo de 2013 |
JSR 343 |
2.1 |
Septiembre de 2017 |
JSR 368 retirado |
JSR 343: JMS (Java Message Service) 2.0
JSR 368: JavaTM Message Service 2.1
JMS ya no es una prioridad para Java EE 8.
Necesita un proveedor de servicios para JMS.
A continuación, se muestra una lista de proveedores open source:
Producto |
Proveedor |
ActiveMQ |
Apache |
OpenJMS |
Collectif |
JBoss Messaging |
JBoss |
HornetQ |
JBoss |
JORAM/OW2 |
ObjectWeb |
Open Message Queue |
Sun Microsystem |
También hay implementaciones propietarias, como BEA Weblogic y Oracle AQ de Oracle, WebSphere MQ de IBM y SAP NetWeaver de SAP, que son útiles en contextos de uso adaptados.
Para los ejemplos que ilustran JMS, usaremos ActiveMQ (http://activemq.apache.org/), de Apache, que soporta JMS desde la versión 1.1 y J2EE 1.4.
La versión 5.17.0 de Active MQ se lanzó en marzo de 2021. Esta versión también soporta AMQP v1.0 y MQTT v3.1. Funciona con Spring 5.x, Log4j 2.x, JDK 11+. Active MQ se puede montar en la memoria para las pruebas JUnit. Su utilización con Spring es muy sencilla, si se usan las clases JmsInvokerServiceExporter y JmsInvokerProxyFactoryBean.
Utilización simplificada
He aquí...
RabbitMQ
RabbitMQ se basa en AMQP y fue creado por Pivotal. Tiene licencia Mozilla Public License. Toma el relevo de ActiveMQ.
1. Spring AMQP y RabbitMQ
En el mundo de los intercambios de mensajes asíncronos, el lado del productor y del consumidor están desacoplados. Un productor produce un mensaje en un área lógica llamada Exchange. Publicamos un mensaje a través de la routing key. La cola está determinada por esta routing key, pero el productor no sabe qué cola se utilizará para transmitir su mensaje.
El consumidor declara una cola, se inscribe respecto a un exchange y define una binding key que indica la regla de enrutamiento que permite que el mensaje se le reenvíe.
Esto permite filtrar los mensajes que desea recibir en el área Exchange.
Los intercambios son de dos tipos:
-
Fanout: enviamos mensajes en broadcast sin reglas de enrutamiento o routing.
-
Direct: correspondencia entre la routing key y la binding key.
-
Topic: para una routing key, posibilidad de utilizar comodines (wildcards) en la binding key.
Podemos modelar de la siguiente manera:
Elemento |
Pattern |
Observaciones |
Exchange |
Business domain |
|
Queue |
service |
Consume los mensajes |
Routing key |
Tipo de evento enviado |
|
Binding key |
Agregador de eventos para un servicio |
|
En una aplicación de microservicio, por ejemplo, se separan las funcionalidades y los eventos se propagan a través de diferentes «nodos» de aplicación. Vemos que los mensajes están muy orientados al streaming de mensajes.
Si separamos las funcionalidades, podemos escalar las partes que lo solicitan...
Puntos clave
-
Los MOM son muy útiles para comunicar los microservicios o aplicaciones monolíticas.
-
No hay muchas diferencias a nivel de código entre las diferentes soluciones de MOM.
-
Tenga en cuenta que la arquitectura puede evolucionar.
-
Los MOM permiten eliminar la tensión en ciertos cuellos de botella, suavizando la carga en las llamadas.