Clustering RabbitMQ: Configurazione, Setup e Best Practices
Scopri la potenza della messaggistica scalabile e resiliente con il clustering RabbitMQ. Questa guida copre concetti essenziali come tipi di nodo, partizioni di rete e sincronizzazione dei dati. Impara passo dopo passo come configurare un cluster RabbitMQ, configurare code ad alta disponibilità (HA) utilizzando le policy e implementare best practice per un deployment e una gestione robusti. Perfetto per sviluppatori e operatori che vogliono costruire applicazioni guidate da messaggi fault-tolerant.
Clustering RabbitMQ: Configurazione, Setup e Best Practices
Il clustering di RabbitMQ è spesso frainteso. Un cluster ti offre un unico broker logico composto da più nodi Erlang. Condivide utenti, vhost, exchange, binding, policy e altri metadati tra questi nodi. Non rende automaticamente disponibili i messaggi di ogni coda ovunque. La disponibilità della coda dipende dal tipo di coda e dalle sue impostazioni di replica.
Questa differenza è importante in produzione. Un cluster può semplificare la gestione e il routing, e può supportare code ad alta disponibilità, ma non è un interruttore magico per le prestazioni. Se metti tutte le code calde su un nodo, quel nodo farà comunque il lavoro. Se usi code classiche senza replica e il nodo leader della coda scompare, quella coda non sarà disponibile fino al ritorno del nodo. Progetta il cluster attorno alle code che effettivamente esegui.
Cosa condivide un cluster e cosa no
I metadati del cluster RabbitMQ sono replicati. Se dichiari un exchange su un nodo, gli altri nodi lo sanno. Se aggiungi un utente o una policy, il cluster memorizza quella definizione. Le applicazioni client possono connettersi a qualsiasi nodo e utilizzare la stessa topologia.
I messaggi sono diversi. Una coda ha un leader. Per le code classiche, i messaggi vivono sul nodo che ospita quella coda a meno che non si utilizzino code mirrorate più vecchie. Per le code quorum, RabbitMQ replica i dati della coda attraverso un gruppo di nodi utilizzando un protocollo di consenso. Per gli stream, i dati vengono replicati secondo la configurazione dello stream. Nelle distribuzioni RabbitMQ moderne, le code quorum sono solitamente la scelta più sicura per code di lavoro durevoli e replicate.
Articoli più vecchi parlano spesso di "code HA" come se fosse il default moderno. Nella terminologia RabbitMQ, di solito si intendono code classiche mirrorate configurate tramite policy. Esistono ancora in alcune installazioni, ma le code quorum sono la direzione che la maggior parte dei nuovi progetti di code durevoli replicate dovrebbe considerare. Controlla sempre la versione di RabbitMQ e i vincoli operativi del tuo ambiente prima di migrare un carico di lavoro esistente.
Prima di unire i nodi
Fai prima i controlli noiosi:
- I nodi devono risolvere i nomi host degli altri in modo coerente.
- La porta di distribuzione Erlang e le porte RabbitMQ devono essere raggiungibili tra i nodi.
- Le versioni di RabbitMQ ed Erlang devono essere compatibili in tutto il cluster.
- Tutti i nodi devono condividere lo stesso cookie Erlang.
- La sincronizzazione dell'ora deve essere sensata, specialmente se il monitoraggio e TLS dipendono da essa.
Il cookie Erlang è un segreto condiviso utilizzato dai nodi Erlang. Su molti pacchetti Linux si trova in /var/lib/rabbitmq/.erlang.cookie, di proprietà dell'utente rabbitmq e con permessi 600.
sudo systemctl stop rabbitmq-server
sudo install -o rabbitmq -g rabbitmq -m 600 .erlang.cookie /var/lib/rabbitmq/.erlang.cookie
sudo systemctl start rabbitmq-server
Non rigenerare casualmente il cookie su un cluster in esecuzione. Se un nodo ha un cookie diverso, non riuscirà a comunicare con gli altri e il messaggio di errore non è sempre amichevole.
Unire un nodo
Supponiamo che rabbit@rmq-a sia già in esecuzione e rabbit@rmq-b debba unirsi ad esso. Su rmq-b:
sudo rabbitmqctl stop_app
sudo rabbitmqctl reset
sudo rabbitmqctl join_cluster rabbit@rmq-a
sudo rabbitmqctl start_app
Poi verifica da qualsiasi nodo:
rabbitmqctl cluster_status
rabbitmq-diagnostics cluster_status
reset rimuove il database RabbitMQ del nodo locale prima di unirsi. Di solito è quello che vuoi per un nuovo nodo vuoto. Non è qualcosa da eseguire con leggerezza su un nodo che possiede code a cui tieni.
Per tre nodi, ripeti lo stesso processo da rmq-c. Puoi unire sia rmq-b che rmq-c a rmq-a; una volta uniti, non esiste un "master" permanente per i metadati nel modo in cui a volte le persone immaginano.
Metti i client dietro un endpoint stabile
Le applicazioni non dovrebbero avere un unico host broker hard-coded se prevedi manutenzione dei nodi. Usa un load balancer, una strategia DNS o un elenco di connessioni della libreria client. Il load balancer dovrebbe verificare se l'applicazione RabbitMQ è in esecuzione, non solo se la porta 5672 è aperta.
Un semplice controllo TCP potrebbe inviare i client a un nodo che è vivo ma bloccato da allarmi o non completamente unito. In ambienti più rigorosi, usa controlli di salute esposti tramite il plugin di gestione o un piccolo controllo locale che esegue rabbitmq-diagnostics -q ping.
Scegli i tipi di coda deliberatamente
Per carichi di lavoro durevoli e replicati, una coda quorum è spesso un buon default:
rabbitmqadmin declare queue name=orders.pending durable=true arguments='{"x-queue-type":"quorum"}'
O tramite dichiarazione dell'applicazione:
channel.queue_declare(
queue='orders.pending',
durable=True,
arguments={'x-queue-type': 'quorum'}
)
Le code quorum sacrificano un po' di throughput e latenza per un comportamento di replica più forte. Non sono un aggiornamento gratuito per ogni coda. Per code di risposta temporanee, subscriber fanout di breve durata o lavoro transitorio di basso valore, le code classiche possono andare bene. Per eventi aziendali che devono sopravvivere alla perdita di un nodo, usa un tipo di coda replicata e testa il failover.
Le partizioni di rete sono un evento operativo, non una casella da spuntare
Una partizione di rete significa che i nodi del cluster non possono parlare tra loro. RabbitMQ ha strategie di gestione delle partizioni, ma nessuna di esse trasforma una rete rotta in una sana. La risposta giusta è progettare il cluster in modo che le partizioni siano rare, visibili e recuperate con attenzione.
Per la maggior parte dei cluster di produzione, usa un numero dispari di nodi per carichi di lavoro basati su quorum ed evita di estendere un piccolo cluster su collegamenti inaffidabili. Tre nodi in tre zone di disponibilità possono funzionare bene se la latenza è accettabile. Due nodi divisi in due siti è una fonte comune di decisioni dolorose perché non c'è maggioranza se il collegamento si interrompe.
Dopo una sospetta partizione, controlla:
rabbitmqctl cluster_status
rabbitmq-diagnostics alarms
rabbitmq-diagnostics check_running
rabbitmqctl list_queues name type leader members online state
Se i leader delle code si sono spostati o i membri sono andati offline, non dare per scontato che l'applicazione stia bene perché le connessioni sono state ripristinate. Tieni d'occhio i publisher confirms, i tassi di errore dei consumer e i messaggi non accusati.
Abitudini di manutenzione che prevengono sorprese nel cluster
Scarica le connessioni prima di fermare un nodo quando possibile. Se hai messo i client dietro un load balancer, rimuovi il nodo dalla rotazione, attendi che i client si riconnettano altrove, poi riavvia RabbitMQ.
Controlla periodicamente la distribuzione delle code:
rabbitmqctl list_queues name type leader messages consumers
Se ogni leader di coda calda si trova su un nodo, il cluster non è bilanciato per quel carico di lavoro. Potresti dover ridichiarare le code, rivedere le policy o utilizzare le impostazioni del localizzatore del leader della coda appropriate per la tua versione di RabbitMQ.
Tieni le policy sotto controllo di versione. Una policy che cambia il tipo di coda, il dead-lettering, la lunghezza massima o il comportamento di mirroring è infrastruttura di produzione, non una modifica dell'interfaccia utente.
I backup contano ancora. Il clustering non sostituisce l'esportazione delle definizioni, l'automazione dell'infrastruttura o la pianificazione del disaster recovery. Esporta le definizioni dopo i cambiamenti di topologia:
rabbitmqadmin export rabbitmq-definitions.json
Infine, testa il fallimento che pensi di poter sopravvivere. Ferma un nodo che detiene un leader di coda. Uccidi un consumer mentre ha messi non accusati. Blocca un publisher durante un allarme disco in staging. Un cluster RabbitMQ guadagna fiducia attraverso prove noiose, non attraverso un diagramma con tre nodi sopra.