Una introducción a RabbitMQ – ¿Qué es RabbitMQ?

¿Por qué Rabbit? ¿Qué es MQ? Cómo puede mejorar nuestras aplicaciones? ¿Por qué querría aprender más sobre él? – Estas son las preguntas que me hice cuando me presentaron RabbitMQ por primera vez. Soy Gabor, y ahora soy ingeniero y consultor de RabbitMQ. En mi tiempo de trabajo con RabbitMQ, he aprendido que incluso los clientes experimentados se hacen estas preguntas.

TL;DR >Consulte nuestra página de producto RabbitMQ para ver los casos de uso, las características y para contactar con nuestros consultores expertos.

¿Qué problema resuelve RabbitMQ?

Antes de profundizar en qué es RabbitMQ y cómo usarlo, vale la pena aprender más sobre el dominio del problema en sí. La comunicación entre diferentes servicios (también conocidos como ordenadores) es un problema antiguo.

Por un lado, están los diferentes protocolos que definen los medios de transporte y las propiedades de la comunicación. Algunos ejemplos de estos protocolos son SMTP, FTP, HTTP o WebSockets (por nombrar algunos), todos ellos basados en TCP/UDP. Se ocupan del formato, la fiabilidad y la búsqueda del destinatario correcto de un mensaje.

Por otro lado, podemos explorar la comunicación desde la perspectiva del mensaje. Existe en un sistema, luego se transporta a otro, se transforma, es decir, tiene un ciclo de vida. Mientras viaja de un sistema a otro, debemos saber dónde está el mensaje y a quién pertenece en un momento dado.

Los protocolos de comunicación mencionados anteriormente pueden asegurar que la propiedad (y la ubicación «física») del mensaje se transfiere de un sistema a otro (aunque puede llevar algún tiempo ejecutar esta transacción). Podemos considerar la transferencia como una transacción entre las dos partes mientras ambas están presentes. La mayoría de las veces, este intercambio activo es deseable, por ejemplo, al preguntar por el estado del servicio y esperar una respuesta puntual y precisa. Un ejemplo del mundo físico sería llamar a alguien por teléfono:
1) iniciamos la llamada,
2) esperamos a que la otra parte conteste,
3) mantenemos una agradable conversación,
4) colgamos el teléfono.

Pero hay otras ocasiones en las que no necesitamos la respuesta, sólo necesitamos que el receptor se haga cargo del mensaje y haga su trabajo. En este caso, necesitamos un agente intermediario, otro sistema que se apropie del mensaje (temporalmente) y se asegure de que el mensaje llega a su destino. Para ampliar el ejemplo del teléfono, la otra parte no está disponible en ese momento, así que dejamos un mensaje de voz. El servicio de correo de voz notificará al receptor previsto.

Esta entrega asíncrona (retrasada) de mensajes es lo que proporciona RabbitMQ. Obviamente, puede hacer más que un simple contestador automático, así que vamos a explorar algunas de las opciones que proporciona a continuación

(Si estás interesado en aprender más sobre la historia de RabbitMQ, te recomiendo el primer capítulo de «RabbitMQ in Action» de Álvaro Videla y Jason Williams. Revelará la respuesta al porqué de su nombre de conejo).

RabbitMQ es una solución de colas de mensajes gratuita, de código abierto y extensible. Es un broker de mensajes que entiende AMQP (Advanced Message Queuing Protocol), pero también es capaz de ser utilizado con otras soluciones de mensajería populares como MQTT. Es altamente disponible, tolerante a fallos y escalable. Está implementado en Erlang OTP, una tecnología diseñada para construir sistemas estables, fiables, tolerantes a fallos y altamente escalables que poseen capacidades nativas para manejar un gran número de operaciones concurrentes, como es el caso de RabbitMQ y otros sistemas como WhatsApp, MongooseIM, por mencionar algunos.

A un nivel muy alto, es una capa de middleware que permite a los diferentes servicios de su aplicación comunicarse entre sí sin preocuparse por la pérdida de mensajes, mientras que proporciona diferentes requisitos de calidad de servicio (QoS). También permite un enrutamiento de mensajes eficiente y de grano fino que permite un amplio desacoplamiento de las aplicaciones.

Casos de uso

Para mostrar la versatilidad de RabbitMQ, vamos a utilizar tres casos de estudio que demuestran cómo RabbitMQ es muy adecuado como un enfoque de servicio gestionado de caja negra, como uno que se integra estrechamente con la aplicación permitiendo una arquitectura de microservicios que funciona bien, o como una puerta de entrada a otros proyectos heredados.

RabbitMQ como bus de mensajes general

Cuando un sistema monolítico se descompone en subsistemas separados, uno de los mayores problemas que hay que resolver es qué tecnología de comunicación utilizar. Una solución como Mulesoft, o MassTransit puede «cablear» servicios declarando oyentes y emisores HTTP. Este tipo de solución trata a RabbitMQ como una caja negra, pero sigue siendo capaz de aprovechar las capacidades de RabbitMQ. Como ejemplo de comunicación directa, vamos a utilizar HTTP para «conectar» los servicios individuales. Aunque es una opción bien soportada y sólida, tiene algunos inconvenientes:
1) El descubrimiento de los servicios no está resuelto. Una posible solución es utilizar DNS. A medida que el sistema escala y crece, también lo hace la complejidad de encontrar y equilibrar esta carga. RabbitMQ puede mitigar el aumento de la complejidad de la solución.
2) La comunicación es efímera. Los mensajes son propensos a ser caídos o duplicados en la capa de red. Si un servicio no está disponible temporalmente, la entrega falla.

RabbitMQ puede ayudar en ambos casos utilizando colas de mensajes como medio de transporte. Los servicios pueden publicar y consumir mensajes, lo que desvincula la entrega de mensajes de extremo a extremo de la disponibilidad del servicio de destino. Si un servicio consumidor no está disponible temporalmente, a diferencia de HTTP, el mensaje se almacena en el búfer de forma segura y se retiene en RabbitMQ, y finalmente se entrega cuando el servicio vuelve a estar en línea.

La capacidad de descubrimiento también se simplifica. Todo lo que necesitamos saber es dónde está RabbitMQ y cuál es el nombre de la cola. Aunque parece que esto reinventa el problema, es escalable. El nombre de la cola actúa como la dirección del servicio. El consumo de mensajes de las colas por parte de los servicios individuales ofrece un medio para la escalabilidad, es decir, cada cola puede servir a múltiples consumidores y equilibrar la carga. No es necesario cambiar la configuración de las colas ya incorporada en los servicios.

Esta configuración de colas moderadamente estática empuja a RabbitMQ a una capa de middleware en la que un diseño sólido puede garantizar una calidad de servicio estable a largo plazo.

RabbitMQ como capa de enrutamiento avanzada para microservicios

En el otro extremo del espectro se encuentra una arquitectura que es más fluida y se adapta a las necesidades siempre cambiantes de muchos microservicios. Lo que hace brillar a RabbitMQ en este entorno son las potentísimas capacidades de enrutamiento que proporciona.

La lógica de enrutamiento se implementa en diferentes (llamados) tipos de intercambio que pueden ser creados dinámicamente por la aplicación cuando sea necesario. Los servicios de destino crean las colas de las que desean consumir, y luego las vinculan a los intercambios especificando un patrón para las claves que los editores pueden utilizar al publicar el mensaje. (Piense en estas claves como metadatos que los intercambios pueden utilizar para enrutar y entregar los mensajes a una o más colas.)

La lógica de enrutamiento se implementa en diferentes (llamados) tipos de intercambio que pueden ser creados dinámicamente por la aplicación cuando sea necesario. Los servicios de destino crean las colas de las que desean consumir, y luego las vinculan a los intercambios especificando un patrón para las claves que los editores pueden utilizar al publicar el mensaje. (Piense en estas claves como metadatos que los intercambios pueden utilizar para enrutar y entregar los mensajes a una o más colas.)

RabbitMQ viene con cuatro tipos de intercambio útiles que cubren la mayoría de los casos de uso de la mensajería:
1) Intercambio directo. Esto entregará el mensaje entrante a cualquier cola cuya clave de enlace coincida exactamente con la clave de enrutamiento del mensaje. Si se vinculan las colas con el nombre de la cola como claves de enrutamiento, entonces se puede pensar en ello como una entrega de mensajes uno a uno. Es sencillo entregar el mismo mensaje a múltiples colas utilizando las claves de enlace para múltiples colas.
2) Intercambio de temas. Esto entregará el mensaje entrante a cualquier cola cuya clave de enlace comodín coincida con la clave de enrutamiento del mensaje publicado. Las claves de enlace pueden contener criterios de coincidencia de comodines para una clave de enrutamiento compuesta. (Por ejemplo, la clave de enlace logs.*.error coincidirá con las claves de enrutamiento logs.accounting.error y logs.ui.error). Esto nos permite escribir servicios simples donde la lógica está bien contenida, y el mensaje llegará a los servicios correctos a través de la «magia» de RabbitMQ.
3) Intercambio Fanout. Algunos mensajes necesitan ser entregados a todas las colas, aquí es donde se puede utilizar un intercambio fanout en lugar de escribir una elaborada lógica multicast en la aplicación. Con un intercambio RabbitMQ fanout, cada servicio vincula la cola apropiada al intercambio sin necesidad de especificar una clave de vinculación, y todo sucede automáticamente. Si se especifica una clave de vinculación, el intercambio fanout simplemente la ignorará y seguirá enrutando/emitiendo mensajes a todas las colas vinculadas a él.
4) Intercambio de cabeceras. Este intercambio aprovecha la estructura de los mensajes AMQP y es capaz de realizar enrutamientos complejos basados en las cabeceras (incluidas las personalizadas) del mensaje AMQP. Las cabeceras son metadatos que se adjuntan a cada mensaje enviado a través de AMQP.

Además de los intercambios, hay otras características útiles en RabbitMQ que permiten la implementación de una lógica de mensajería muy compleja. Algunas de las características más importantes son:
1) Plug-ins personalizados. RabbitMQ es extensible permitiendo a sus usuarios añadir plug-ins. Casi todos los aspectos de RabbitMQ son personalizables, incluyendo la gestión, la autenticación y la autorización, las soluciones de copia de seguridad y el clustering.
2) Clustering. Cuando un solo servidor RabbitMQ no es suficiente, se pueden conectar varios brokers RabbitMQ para trabajar juntos y escalar el sistema. Puede permitir a RabbitMQ procesar más mensajes o aumentar la resistencia a los errores.
3) Ajuste de la calidad del servicio. La entrega de mensajes sensibles al tiempo puede ayudarse adjuntando un valor TTL (Time-to-Live) al mensaje o a la cola. Los mensajes con tiempo de espera pueden ser entregados automáticamente a una cola de espera. La combinación de la lógica de enrutamiento ordinaria y estas características adicionales puede conducir a lógicas de enrutamiento muy avanzadas. Otra característica útil es el uso de colas de prioridad donde el editor puede asignar un nivel de prioridad a cada mensaje. También es posible limitar el número de mensajes no reconocidos, lo que permite ajustar el rendimiento de los servicios consumidores, en este caso, RabbitMQ aplica un mecanismo de contrapresión.

RabbitMQ integrado en sistemas heredados

En el caso de uso anterior, mencioné la posibilidad de utilizar plug-ins para ampliar la funcionalidad de RabbitMQ. Esta potente característica permite a RabbitMQ actuar como una capa de mediación entre sus servicios nativos de RabbitMQ (con capacidad AMQP) y otras aplicaciones heredadas. Algunos ejemplos notables incluyen:
1) Usar RabbitMQ como un broker MQTT simplemente habilitando un plug-in. Esto abre el panorama a muchas tecnologías IoT.
2) El plugin JMS (Java Message Service) de RabbitMQ, que permite a RabbitMQ comunicarse con cualquier solución de mensajería con capacidad JMS.
3) Si su aplicación utiliza un protocolo propietario para comunicarse, es posible desarrollar un plugin personalizado para conectarse a cualquiera de estos servicios.

Conclusión

Como demuestran los ejemplos anteriores, no hay casi nada con lo que RabbitMQ no pueda comunicarse. Pero como todo en la vida, tiene un precio. Aunque la configuración de RabbitMQ es en su mayoría sencilla, a veces el mero número de características puede ser abrumador. Si tiene algún problema con el diseño, la implementación o el soporte de sus corredores RabbitMQ, póngase en contacto con nuestro equipo de expertos aquí. O, si desea iniciar su carrera en una de las tecnologías más demandadas, inscríbase en nuestro curso de formación de 3 días sobre RabbitMQ.

Debugging RabbitMQ

¿Quiere un sistema intuitivo que facilite la supervisión y el mantenimiento de su RabbitMQ? Obtenga su prueba gratuita de 45 días de WombatOAM ahora.

Nuestra página de capacidades de RabbitMQ