RabbitMQ è un eccellente progetto open-source che consente di fornire centinaia di migliaia di messaggi al secondo per l’applicazione in modo rapido ed efficiente. La seguente voce presenta il modo in cui è possibile posizionare un cluster RabbitMQ di tre host separati. A tale scopo, useremo Docker e ci collegheremo al cluster pronto utilizzando il nodo.js.

Informazioni su RabbitMQ

RabbitMQ è un sistema di accodamento basato sul protocollo AMQP, il sistema stesso è stato scritto in Erlang. Grazie all’uso di questo linguaggio, RabbitMQ è ideale per l’uso come bus dati centrale nell’architettura dei microservizi. Tale binario fornisce un ottimo substrato per applicazioni che consentono un’ampia gamma dinamica di sviluppo nel paradigma DDD e CQRS. Poiché il bus dati (coda di messaggi) è la spina dorsale dell’architettura, è importante che sia sempre disponibile e resistente ai guasti. L’architettura ridondante diventa la scelta naturale, ovvero la replica dei dati in nodi esecutivi separati.

La replica in RabbitMQ è supportata nativamente in modalità master-slave. Ciò significa che RabbitMQ selezionerà sempre un nodo per ogni coda creata e reindirizzerà tutti i messaggi ad esso per il salvataggio, oltre a recuperare i messaggi da esso per la lettura dalla coda, gli altri nodi (slave) fungono da replicatore di dati pronto a assumere il ruolo del nodo master in ogni momento. Sebbene il senso più grande sia la replica quando i nodi sono sparsi su macchine fisiche diverse, in questo caso userò un esempio di replica all’interno della stessa macchina. RabbitMQ a causa del suo scopo, ovvero centinaia di migliaia di messaggi supportati al secondo, non è preferito in modalità di replica su macchine che non si trovano nello stesso rack del server. Ciò è dovuto al fatto che i messaggi rimangono in coda molto breve e le ipotesi non dovrebbero andare oltre la RAM, replicarli sulla base di una connessione di rete in una parte diversa del data center o ad un data center completamente diverso significherebbe drastiche diminuzioni delle prestazioni, e in questa classe di sistema non può essere consentito. Inoltre, posizionando i nodi RabbitMQ vicini l’uno all’altro, riduciamo al minimo il rischio della cosiddetta partizione di rete (che è molto improbabile nel caso di una roulette), ad es. il fenomeno di interrompere la comunicazione tra i nodi in modo tale che almeno 2 nodi dell’intero cluster si considerino master. Maggiori informazioni sulla partizione di rete nel contesto di RabbitMQ possono essere lette qui.

Pertanto, la regola basata sulla pratica mette RabbitMQ in modalità di replica solo nello stesso data center.

Download di immagini Docker

Presumo che tu sappia cos’è Docker e come usarlo, perché nella parte successiva della voce lo useremo ampiamente

Per iniziare, inizia scaricando le immagini RabbitMQ appropriate (insieme al plug-in del pannello di amministrazione) e il Nodo.js, a questo scopo usiamo i seguenti comandi:

docker pull 3.6.6-managementdocker pull node:11.10.1

Setup RabbitMQ hosts

Ai fini della presentazione, lanceremo un’immagine RabbitMQ a cui ci collegheremo con il comando docker exec e invocheremo la shell bash per poter eseguire la configurazione a modo nostro. Usiamo il comando:

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

Il comando precedente eseguirà l’immagine da RabbitMQ che verrà eliminata dopo aver lasciato la shell. L’istanza verrà collegata alla nostra interfaccia di rete in modo da non doverci preoccupare del port forwarding. Se la shell [email protected]:/# è apparsa ai nostri occhi, significa che tutto è andato bene.

Il passo successivo è quello di eseguire tre processi RabbitMQ su porte separate, ogni processo riceverà un nome univoco.

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

Successivamente, con l’aiuto di rabbitmqctl, colleghiamo entrambi i nodi alla radice con il nome 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

Dopo tutto, possiamo aprire il browser e inserire l’indirizzo http://localhost:15672 per verificare che tutto sia andato bene, la console di gestione del cluster dovrebbe puntare a tutti i nodi come nella schermata sottostante.

Importante. Non disabilitare la shell del contenitore da RabbitMQ poiché questa la rimuoverà (l’opzione rm rm sul comando di avvio Docker)

Abbiamo l’ultima cosa da fare, sebbene il cluster RabbitMQ sia pronto, dobbiamo configurare le politiche appropriate. Questa funzione è implementata utilizzando il pannello di amministrazione, ulteriori informazioni su High availability (HA) in RabbitMQ possono essere lette nella documentazione.

Sopra è un esempio di configurazione della politica HA. E di seguito è riportato il metodo di verifica. Il numero + 2 nel nome del nodo indica il numero di host separati a cui viene replicata la coda.

Installazione e download della libreria amqp sul nodo.js

Il passo successivo è avviare l’istanza del contenitore Docker con il Nodo.immagine js, a questo scopo, eseguire il seguente comando che condivide anche l’interfaccia di rete.

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

Quindi nel luogo scelto dal nostro sito (ad esempio /home) creiamo una directory in cui inseriamo gli script necessari e installiamo la libreria amqp-connection-manager che consente la connessione a RabbitMQ (o altro sistema che implementa il protocollo AMQP) dal livello di Nodo.js.

npm install --save amqp-connection-manager

Inoltre, la libreria consente l’aggiunta di diversi indirizzi host RabbitMQ fornendo un meccanismo per riconnettersi in caso di errore di qualsiasi host. Questa è una funzionalità molto utile, perché si preoccupa di una connessione corretta con RabbitMQ e in caso di errore può rilevare i messaggi in memoria fino a quando la connessione non appare indietro.

Sample producer-consumer code

Ora che abbiamo preparato tutti i componenti, possiamo iniziare a creare un semplice codice responsabile della creazione e della ricezione dei messaggi. A tale scopo, creeremo due file e li riempiremo con un codice.

produttore.js-lo script si connette all’istanza RabbitMQ e inizia a inviare 10 messaggi al secondo.

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()

consumatore.js-lo script si connette all’istanza RabbitMQ e inizia a leggere i messaggi dalla coda.

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()

I file creati in questo modo possono essere eseguiti separatamente utilizzando Node.js e guarda come consumer.js riceve i dati prodotti da producer.js. Per verificare l’operazione di replica nel cluster RabbitMQ, ti incoraggio a disabilitare durante lo scambio di dati tramite script uno dei processi RabbitMQ per vedere come verrà gestito l’errore e come RabbitMQ selezionerà il nuovo master e reindirizzerà i messaggi di conseguenza.

rabbitmqctl -n john stop_app

La disattivazione di una delle istanze RabbitMQ non influisce sulla produzione o sul download dei messaggi. Le code vengono replicate automaticamente e la connessione ripristinata senza la necessità di implementare i propri meccanismi.

In sintesi, RabbitMQ è un ottimo sistema di accodamento che garantisce un’elevata disponibilità dopo una configurazione corretta che non causa molti problemi. Un gran numero di librerie in molte lingue, ad esempio Nodo.js, PHP, Java, Python, Golang, C / C++, consente una facile implementazione del sistema nel progetto. Raccomando a tutti di leggere la documentazione che spiega molto chiaramente i problemi relativi al funzionamento del sistema e alla sua corretta configurazione, che è davvero ampia.

Tutto il codice è conservato nel repository su Github

Ricerche simili: nodejs rabbitmq / nodejs queue / rabbitmq queue nodejs