RabbitMQ es un excelente proyecto de código abierto que le permite entregar cientos de miles de mensajes por segundo a su aplicación de forma rápida y eficiente. La siguiente entrada presenta la forma en que puede colocar un clúster RabbitMQ de tres hosts separados. Para este propósito, usaremos Docker y nos conectaremos al clúster listo mediante el nodo.js.

Acerca de RabbitMQ

RabbitMQ es un sistema de colas basado en el protocolo AMQP, el sistema en sí fue escrito en Erlang. Gracias al uso de este lenguaje, RabbitMQ es ideal para su uso como bus de datos central en la arquitectura de microservicios. Este riel proporciona un gran sustrato para aplicaciones que permiten un amplio rango dinámico de desarrollo en el paradigma DDD y CQRS. Dado que el bus de datos (cola de mensajes) es la columna vertebral de la arquitectura, es importante que esté siempre disponible y resistente a fallos. La arquitectura redundante se convierte en la elección natural, es decir, la replicación de datos en nodos ejecutivos separados.

La replicación en RabbitMQ se admite de forma nativa en modo maestro-esclavo. Esto significa que RabbitMQ siempre seleccionará un nodo para cada cola creada y redirigirá todos los mensajes a ella para guardarlos, así como recuperar mensajes de ella para leerlos de la cola, los otros nodos (esclavos) actúan como replicadores de datos listos para asumir el papel del nodo maestro en todo momento. Aunque el mayor sentido es la replicación cuando los nodos están dispersos en diferentes máquinas físicas, en este caso usaré un ejemplo de replicación dentro de la misma máquina. RabbitMQ debido a su propósito, es decir, cientos de miles de mensajes admitidos por segundo, no se prefiere en el modo de replicación en máquinas que no están en el mismo rack de servidores. Esto se debe al hecho de que los mensajes permanecen en la cola muy cortos y las suposiciones no deben ir más allá de la RAM, replicarlos basados en una conexión de red en una parte diferente del centro de datos o en un centro de datos completamente diferente significaría disminuciones drásticas en el rendimiento, y en esta clase de sistema no se puede permitir. Además, al colocar nodos RabbitMQ cerca unos de otros, minimizamos el riesgo de la llamada partición de red (que es muy poco probable en el caso de una ruleta), es decir, el fenómeno de interrumpir la comunicación entre nodos de tal manera que al menos 2 nodos de todo el clúster se consideren maestros. Puede leer más sobre la partición de red en el contexto de RabbitMQ aquí.

Por lo tanto, la regla basada en la práctica es poner RabbitMQ en modo de replicación solo en el mismo centro de datos.

Descargar imágenes de Docker

Asumo que sabe qué es Docker y cómo usarlo, porque en la siguiente parte de la entrada lo usaremos ampliamente

Para comenzar, comience descargando las imágenes RabbitMQ apropiadas (junto con el complemento del panel de administración) y el nodo.js, para ello utilizamos los siguientes comandos:

docker pull 3.6.6-managementdocker pull node:11.10.1

Configurar hosts RabbitMQ

Para los fines de la presentación, lanzaremos una imagen RabbitMQ a la que conectaremos con el comando docker exec e invocaremos el shell bash para poder ejecutar la configuración a nuestro modo. Usemos el comando:

docker run --hostname rabbit --name rabbit --rm -ti --net="host" rabbitmq:3.6.6-management /bin/bash

El comando anterior ejecutará la imagen desde RabbitMQ que se eliminará después de salir del shell. La instancia se conectará a nuestra interfaz de red para que no tengamos que preocuparnos por el reenvío de puertos. Si el caparazón [email protected]:/# apareció a nuestros ojos, significa que todo salió bien.

El siguiente paso es ejecutar tres procesos RabbitMQ en puertos separados, cada proceso recibirá un nombre único.

RABBITMQ_NODE_PORT=5672 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener " RABBITMQ_NODENAME=rabbit rabbitmq-server -detachedRABBITMQ_NODE_PORT=5673 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener " RABBITMQ_NODENAME=hare rabbitmq-server -detachedRABBITMQ_NODE_PORT=5674 RABBITMQ_SERVER_START_ARGS="-rabbitmq_management listener " RABBITMQ_NODENAME=john rabbitmq-server -detached

A continuación, con la ayuda del rabbitmqctl, adjuntamos ambos nodos a la raíz con el nombre rabbit:

rabbitmqctl -n hare stop_apprabbitmqctl -n hare join_cluster [email protected]`hostname -s`rabbitmqctl -n hare start_apprabbitmqctl -n john stop_apprabbitmqctl -n john join_cluster [email protected]`hostname -s`rabbitmqctl -n john start_app

Después de todo, podemos abrir el navegador e ingresar la dirección http://localhost:15672 para verificar que todo salió bien, la consola de administración del clúster debe apuntar a todos los nodos como en la pantalla de abajo.

Importante. No deshabilite el shell del contenedor de RabbitMQ, ya que esto lo eliminará (la opción rm rm en el comando de inicio de Docker)

Tenemos lo último que hacer, aunque el clúster de RabbitMQ está listo, necesitamos configurar las políticas apropiadas. Esta función se implementa utilizando el panel de administración, se puede leer más información sobre alta disponibilidad (HA) en RabbitMQ en la documentación.

El ejemplo anterior es un ejemplo de configuración de directivas de HA. Y a continuación se muestra el método de verificación. El número + 2 en el nombre del nodo significa el número de hosts separados en los que se replica la cola.

Instalación y descarga de la biblioteca amqp en el nodo.js

El siguiente paso es iniciar la instancia de contenedor de Docker con el nodo.js image, para este propósito, ejecute el siguiente comando que también comparte la interfaz de red.

docker run -ti --rm --net="host" node:11.10.1 /bin/bash

Luego en el lugar elegido por nuestro sitio (por ejemplo /home) creamos un directorio en el que colocamos los scripts necesarios e instalamos la biblioteca amqp-connection-manager que permite la conexión a RabbitMQ (u otro sistema que implementa el protocolo AMQP) desde el nivel de Nodo.js.

npm install --save amqp-connection-manager

Además, la biblioteca permite la adición de varias direcciones de host RabbitMQ que proporcionan un mecanismo para volver a conectarse en caso de fallo de cualquier host. Esta es una funcionalidad muy útil, ya que se preocupa por una conexión adecuada con RabbitMQ y, en caso de fallo, puede detectar mensajes en la memoria hasta que la conexión vuelva a aparecer.

Código de muestra de productor-consumidor

Ahora que tenemos todos los componentes preparados, podemos comenzar a crear un código simple responsable de crear y recibir mensajes. Para ello, crearemos dos archivos y los rellenaremos con un código.

productor.js: el script se conecta a la instancia de RabbitMQ y comienza a enviar 10 mensajes por segundo.

let q = 'tasks';let amqp = require('amqp-connection-manager');function sleep(ms) { if(ms setTimeout(resolve, ms));}let main = async () => { var connection = amqp.connect(); var channelWrapper = connection.createChannel({ json: true, setup: function(channel) { return channel.assertQueue(q, { durable: true }); } }); console.log('Starting message stream') while (true) { await channelWrapper.sendToQueue(q, { value: Math.random() }) await sleep(100) }}main()

consumidor.js: el script se conecta a la instancia de RabbitMQ y comienza a leer mensajes de la cola.

let q = 'tasks';let amqp = require('amqp-connection-manager');let main = async () => { var connection = amqp.connect(); var channelWrapper = connection.createChannel({ json: true, setup: function(channel) { return channel.assertQueue(q, { durable: true }); } }); channelWrapper.addSetup(function(channel) { return Promise.all() });}main()

Los archivos creados de esta manera se pueden ejecutar por separado utilizando Node.js y watch as consumer.js reciben datos producidos por producer.js. Para verificar la operación de replicación en el clúster de RabbitMQ, le animo a desactivar durante el intercambio de datos por scripts uno de los procesos de RabbitMQ para ver cómo se manejará el error y cómo RabbitMQ seleccionará el nuevo maestro y redirigirá los mensajes en consecuencia.

rabbitmqctl -n john stop_app

La desactivación de una de las instancias de RabbitMQ no afecta a la producción o descarga de mensajes. Las colas se replican automáticamente y la conexión se recupera sin necesidad de implementar sus propios mecanismos.

En resumen, RabbitMQ es un gran sistema de colas que garantiza una alta disponibilidad después de una configuración adecuada que no causa muchos problemas. Un gran número de bibliotecas en muchos idiomas, por ejemplo, Node.js, PHP, Java, Python, Golang, C / C++, permite una fácil implementación del sistema en el proyecto. Recomiendo a todos que lean la documentación que explica muy claramente los problemas relacionados con el funcionamiento del sistema y su configuración correcta, que es realmente extensa.

Todo el código se guarda en el repositorio en Github

Búsquedas similares: nodejs rabbitmq / cola de nodejs / cola de rabbitmq nodejs