RabbitMQ è un ottimo broker di messaggi distribuiti ma non è così facile da amministrare a livello di codice. In questo tutorial ti mostrerò come creare un cluster, aggiungere nodi, rimuovere nodi, avviare e fermare. Come bonus condividerò un file Fabric che ti consente di assumere il controllo totale. Il codice è disponibile su GitHub.
RabbitMQ è una coda di messaggi molto popolare. Puoi avere più produttori che inviano messaggi e i consumatori possono consumare questi messaggi in un modo totalmente disaccoppiato. RabbitMQ è molto popolare per diversi motivi:
RabbitMQ è implementato in Erlang, che è un po 'insolito, ma uno dei motivi è così affidabile.
Ai fini di questo tutorial userò un cluster Vagrant locale di tre nodi. Se hai già tre macchine disponibili (virtuali o meno), puoi invece usarle. Presta attenzione alle porte e al networking.
Segui le istruzioni per installare VirtualBox.
Segui le istruzioni per installare Vagrant
Ecco un Vagrantfile che creerà un cluster locale a tre nodi sulla tua macchina. Il sistema operativo è Ubuntu 14.04 (affidabile).
ruby # - * - mode: ruby - * - # vi: set ft = ruby: hosts = "rabbit-1" => "192.168.77.10", "rabbit-2" => "192.168.77.11", "rabbit -3 "=>" 192.168.77.12 " Vagrant.configure (" 2 ") do | config | config.vm.box = "trusty64" hosts.each_with_index do | (name, ip), i | rmq_port = 5672 + i admin_port = 15672 + i config.vm.define nome do | machine | machine.vm.network: private_network, ip: ip config.vm.hostname = "rabbit-% d"% [i + 1] config.vm.network: forwarded_port, guest: 5672, guest_ip: ip, host: rmq_port config. vm.network: forwarded_port, guest: 15672, guest_ip: ip, host: admin_port machine.vm.provider "virtualbox" do | v | v.name = nome fine fine fine fine
Per creare un cluster vuoto, digitare: vagabondo
.
Per semplificare l'esecuzione di ssh nei nodi del cluster, digitare: vagrant ssh-config >> ~ / .ssh / config
.
Se si digita: cat ~ / .ssh / config
, dovresti vedere le voci per coniglio-1, coniglio-2 e coniglio-3.
Ora puoi ssh in ogni macchina virtuale per nome: ssh rabbit-1
.
Il modo più semplice è modificare il file / etc / hosts. Ad esempio, per coniglio-1 aggiungi gli indirizzi di coniglio-2 e coniglio-3.
semplice 192.168.77.11 coniglio-2 192.168.77.12 coniglio-3
Ripeti il processo per tutti i nodi.
Userò apt-get qui per i sistemi operativi Debian / Ubuntu. Se il tuo cluster funziona su un sistema operativo diverso, segui le istruzioni sulla pagina di installazione di RabbitMQ.
Si noti che a volte una versione piuttosto scadente di RabbitMQ è disponibile per impostazione predefinita. Se si desidera installare il più recente e migliore, è possibile scaricare direttamente un pacchetto .deb o aggiungere il repository apt di RabbitMQ, utilizzando queste istruzioni.
La versione attuale di RabbitMQ su Ubuntu 14.04 è 3.2, che è abbastanza buona per i nostri scopi. Verifica tu stesso digitando: apt-cache mostra rabbitmq-server
.
Andiamo avanti e installarlo su ogni macchina:
semplice sudo apt-get update sudo apt-get install rabbitmq-server -y
Sentiti libero di usare il tuo strumento di gestione della configurazione preferito come Chef o Ansible se preferisci.
Si noti che Erlang verrà installato prima come prerequisito.
Il plugin di gestione è davvero interessante. Offre un'API basata su HTTP, una GUI Web e uno strumento da riga di comando per gestire il cluster. Ecco come abilitarlo:
semplici sudo rabbitmq-plugins abilita rabbitmq_management
Scaricalo da http://192.168.77.10:15672/cli/rabbitmqadmin. Si noti che la documentazione di RabbitMQ non è corretta e ti dice di scaricare da http: //
Questo è un client HTTP basato su Python per l'API HTTP di gestione RabbitMQ. È molto conveniente per lo scripting di cluster RabbitMQ.
RabbitMQ implementa lo standard AMQP 0.9.1 (Advanced Message Queue Protocol). Si noti che esiste già uno standard AMQP 1.0 e RabbitMQ ha un plugin per supportarlo, ma è considerato un prototipo a causa di un uso insufficiente del mondo reale.
Nel modello AMQP, i publisher inviano messaggi a un broker di messaggi (RabbitMQ è il broker di messaggi in questo caso) tramite uno scambio. Il broker dei messaggi distribuisce i messaggi alle code in base ai metadati associati al messaggio. I consumatori consumano messaggi dalle code. I messaggi possono o non possono essere riconosciuti. RabbitMQ supporta una varietà di modelli di programmazione su questi concetti come code di lavoro, publish-subscribe e RPC.
Esistono tre script utilizzati per gestire il cluster. Lo script rabbitmq-server avvia un server RabbitMQ (avvialo). Il comando rabbitmqctl viene utilizzato per controllare il cluster (arrestare, reimpostare, raggruppare i nodi insieme e ottenere lo stato). Il comando rabbitmqadmin, scaricato in precedenza, viene utilizzato per configurare e amministrare il cluster (dichiarare vhosts, utenti, scambi e code). La creazione di un cluster coinvolge solo rabbitmq-server e rabbitmqctl.
Innanzitutto, iniziamo il server rabbitmq come servizio (demone) su ciascuno dei nostri host rabbit-1, rabbit-2 e rabbit-3.
semplice servizio sudo rabbitmq-server start
Ciò avvierà sia l'Erlang VM che l'applicazione RabbitMQ se il nodo è inattivo. Per verificare che funzioni correttamente, digita:
plain sudo rabbitmqctl cluster_status
L'output dovrebbe essere (per rabbit-1):
stato di Cluster semplice del nodo 'rabbit @ rabbit-1' ... [nodes, [disc, ['rabbit @ rabbit-1']], running_nodes, ['rabbit @ rabbit-1'], partitions ,[]]… fatto.
Ciò significa che il nodo non è ancora in cluster con nessun altro nodo ed è un nodo disco. È anche in esecuzione come puoi vedere che appare nell'elenco dei nodi in esecuzione.
Per fermare il server, emettere il seguente comando:
plain sudo rabbitmqctl stop_app
Quindi se si controlla lo stato del cluster:
plain sudo rabbitmqctl cluster_status
L'output dovrebbe essere:
semplice stato di Cluster del nodo 'rabbit @ rabbit-1' ... [nodes, [disc, ['rabbit @ rabbit-1']]] done.
Niente più nodi in esecuzione.
Puoi ripetere il processo per gli altri nodi (coniglio-2 e coniglio-3) e vedere che sanno solo loro stessi.
Prima di poter creare un cluster, tutti i nodi nel cluster devono avere lo stesso cookie. Il cookie è un file utilizzato dal runtime Erlang per identificare i nodi. Si trova in /var/lib/rabbitmq/.erlang.cookie. Basta copiare il contenuto da coniglio-1 a coniglio-2 e coniglio-3.
Raggruppare questi nodi separati in un cluster coeso richiede un po 'di lavoro. Ecco la procedura:
Facciamolo. ssh in rabbit-2 ed esegui i seguenti comandi:
plain sudo rabbitmqctl stop_app sudo rabbitmqctl reset sudo rabbitmqctl join_cluster rabbit @ rabbit-1
Adesso scrivi: sudo rabbitmqctl cluster_status
.
L'output dovrebbe essere:
"stato di Cluster semplice del nodo 'rabbit @ rabbit-2' ... [nodes, [disc, ['rabbit @ rabbit-1', 'rabbit @ rabbit-2']]] ... Fatto. Come puoi vedere entrambi i nodi sono ora raggruppati in cluster. Se lo ripeti su rabbit-1 otterrai l'output seguente:
Stato del cluster del nodo "rabbit @ rabbit-1" ... [nodes, [disc, ['rabbit @ rabbit-1', 'rabbit @ rabbit-2']], running_nodes, ['rabbit @ rabbit- 1 '], partitions, []] ... done. "
Ora puoi iniziare con rabbit-2.
plain sudo rabbitmqctl start_app
Se controlli di nuovo lo stato, entrambi i nodi saranno in esecuzione:
stato di Cluster semplice del nodo 'rabbit @ rabbit-2' ... [nodes, [disc, ['rabbit @ rabbit-1', 'rabbit @ rabbit-2']], running_nodes, ['rabbit @ rabbit -1 ',' rabbit @ rabbit-2 '], partitions, []] ... fatto.
Si noti che entrambi i nodi sono nodi disco, il che significa che memorizzano i propri metadati sul disco. Aggiungiamo rabbit-3 come nodo RAM. ssh to rabbit-3 e emettere i seguenti comandi:
plain sudo rabbitmqctl stop_app sudo rabbitmqctl reset sudo rabbitmqctl join_cluster --ram rabbit @ rabbit-2 sudo rabbitmqctl start_app
Il controllo dello stato mostra:
stato di Cluster semplice del nodo 'rabbit @ rabbit-3' ... [nodes, [disc, ['rabbit @ rabbit-2', 'rabbit @ rabbit-1'], ram, ['rabbit @ rabbit-3 ']], running_nodes, [' rabbit @ rabbit-1 ',' rabbit @ rabbit-2 ',' rabbit @ rabbit-3 '], partitions, []] ... fatto.
Tutti i nodi del cluster sono in esecuzione. I nodi Disc sono rabbit-1 e rabbit-2 e il nodo RAM è rabbit-3.
Congratulazioni! Hai un cluster RabbitMQ funzionante.
Cosa succede se si desidera modificare la configurazione del cluster? Dovrai usare la precisione chirurgica quando aggiungi e rimuovi i nodi dal cluster.
Cosa succede se un nodo non viene ancora riavviato, ma si tenta di andare avanti stop_app
, reset
e start_app
? Bene, il comando stop_app apparentemente riuscirà, restituendo "done" anche se il nodo di destinazione è inattivo. Tuttavia, il comando di reset successivo fallirà con un messaggio sgradevole. Ho passato molto tempo a grattarmi la testa cercando di capirlo, perché pensavo che il problema fosse qualche opzione di configurazione che riguardava solo il reset.
Un altro trucco è che se si desidera ripristinare l'ultimo nodo del disco, è necessario utilizzare force_reset
. Cercare di capire nel caso generale quale nodo fosse l'ultimo nodo del disco non è banale.
RabbitMQ supporta anche il clustering tramite file di configurazione. Questo è ottimo quando i nodi del disco sono attivi, poiché i nodi RAM riavviati si limiteranno a cluster in base al file di configurazione senza doverli raggruppare in modo esplicito. Di nuovo, non vola quando si tenta di recuperare un cluster rotto.
Si tratta di questo: non si sa quale sia stato l'ultimo nodo del disco a scendere. Non si conoscono i metadati di clustering di ciascun nodo (forse è andato giù durante il reset). Per avviare tutti i nodi, utilizzo il seguente algoritmo:
Questo algoritmo funzionerà finché l'ultimo nodo del disco sarà fisicamente OK.
Una volta che tutti i nodi del cluster sono attivi, è possibile riconfigurarli (ricordare che non si è sicuri di quali siano i metadati di clustering di ciascun nodo). La chiave è force_reset ogni nodo. Ciò garantisce che qualsiasi traccia della precedente configurazione del cluster venga cancellata da tutti i nodi. Per prima cosa fallo per un nodo del disco:
plain stop_app force_reset start_app
Quindi per ogni altro nodo (disco o RAM):
plain stop_app force_reset join_cluster [elenco dei nodi del disco] start_app
Puoi inserire SSH in ogni casella ed eseguire manualmente i passaggi sopra indicati su ciascuna scatola. Funziona, ma invecchia molto velocemente. Inoltre, non è pratico se si desidera costruire e abbattere un cluster come parte di un test automatico.
Una soluzione è usare Fabric. Una cosa seria che ho incontrato è che quando ho eseguito manualmente l'algoritmo del cluster di build ha funzionato perfettamente, ma quando ho usato Fabric è fallito misteriosamente. Dopo un po 'di debug ho notato che i nodi sono stati avviati con successo, ma quando ho provato a stop_app, i nodi erano inattivi. Questo risultò essere un errore newbie Fabric da parte mia. Quando si invia un comando remoto utilizzando Fabric, viene avviata una nuova shell sulla macchina remota. Al termine del comando, la shell viene chiusa, inviando un SIGHUP (Hang up signal) a tutti i suoi sub-processi, incluso il nodo Erlang. Usando nohup ci si prende cura di questo. Un'altra opzione più efficace è eseguire RabbitMQ come servizio (daemon).
Amministrazione significa creare host virtuali, utenti, scambi e code, impostare permessi e code di binding per gli scambi. La prima cosa che dovresti fare se non lo hai già è installare i plugin di gestione. Non sono sicuro del motivo per cui devi abilitarlo da solo. Dovrebbe essere abilitato di default.
L'interfaccia utente web è fantastica e devi assolutamente familiarizzarti con essa. Tuttavia, per amministrare un cluster in remoto, è possibile utilizzare un'API di gestione RESTful. C'è anche uno strumento da riga di comando Python chiamato rabbitmqadmin che richiede Python 2.6+. Usare rabbitmqadmin è piuttosto semplice. L'unico problema che ho riscontrato è che potevo utilizzare solo l'account guest predefinito per amministrare il cluster. Ho creato un altro utente amministratore chiamato "admin", ho impostato le sue autorizzazioni a tutti (configure / read / write) e gli ho assegnato un tag "administrator" (requisito aggiuntivo dell'API di gestione), ma ho continuato a ricevere errori di autorizzazione.
Il progetto Elmer ti consente di specificare una configurazione del cluster come una struttura dati Python (vedi il file sample_config.py) e imposterà tutto per te.