Risoluzione dei problemi di RabbitMQ: Diagnosi di code e messaggi con i comandi
Padroneggia l'utilità da riga di comando `rabbitmqctl` per una rapida risoluzione dei problemi di RabbitMQ. Questa guida fornisce comandi pratici e attuabili per diagnosticare problemi comuni come arretrati eccessivi di code, messaggi bloccati, connettività zero dei consumatori e binding di exchange errati. Impara le diagnostiche essenziali per ripristinare rapidamente il flusso dei messaggi senza affidarti esclusivamente all'interfaccia utente.
Risoluzione dei problemi di RabbitMQ: Diagnosi di code e messaggi con i comandi
Quando una coda di RabbitMQ sembra bloccata, la prima mossa peggiore è solitamente quella di svuotarla. La seconda mossa peggiore è riavviare il broker e sperare che il problema si risolva. La maggior parte dei problemi delle code lascia una traccia: messaggi pronti, messaggi non riconosciuti, consumatori mancanti, publisher bloccati, messaggi non instradabili, una coda di dead-letter che si riempie silenziosamente o un consumatore che è connesso ma non riconosce nulla.
Questa guida utilizza i comandi di RabbitMQ per restringere il campo dal terminale. Mi affido a rabbitmqctl per lo stato lato broker e a rabbitmqadmin quando sono necessarie operazioni API di gestione come il campionamento sicuro di un messaggio. Gli esempi presuppongono il virtual host predefinito a meno che non venga mostrata un'opzione -p <vhost>. Nei sistemi reali, includi sempre il vhost; molte diagnosi errate avvengono perché qualcuno controlla / mentre l'applicazione usa payments o prod.
Comprendere rabbitmqctl
Il comando rabbitmqctl funge da interfaccia a riga di comando (CLI) per interagire con il layer di gestione di RabbitMQ. Ti consente di gestire utenti, permessi, exchange, code, binding e, cosa più importante per la risoluzione dei problemi, esaminare le statistiche di runtime del broker.
Nota sull'esecuzione: La maggior parte dei comandi richiede privilegi di root o che l'utente che esegue il comando sia membro del gruppo rabbitmq, oppure potrebbe essere necessario usare sudo.
Diagnosticare arretrati di code e messaggi bloccati
Uno dei problemi più comuni è una coda in crescita, che indica che i messaggi vengono prodotti più velocemente di quanto vengono consumati o che i consumatori hanno smesso di elaborarli.
Inizia dalla coda, ma chiedi le colonne giuste
L'output predefinito di list_queues è troppo scarso per la risoluzione dei problemi. Chiedi le colonne che separano "in attesa di essere consegnati" da "consegnati ma non riconosciuti".
rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged messages consumers state
Leggilo in questo modo:
| Sintomo | Significato probabile |
|---|---|
messages_ready in crescita, consumers è 0 |
Nessun consumatore attivo è iscritto alla coda. Controlla distribuzioni, credenziali, vhost e nome della coda. |
messages_ready in crescita, consumatori presenti |
I consumatori sono troppo lenti, bloccati o il prefetch è troppo basso per il carico di lavoro. |
messages_unacknowledged alto e stabile |
I consumatori hanno ricevuto messaggi ma non li stanno riconoscendo. Cerca gestori bloccati o un valore di prefetch troppo alto. |
state non è running |
La coda potrebbe non essere disponibile, essere in sincronizzazione o essere influenzata da un problema del nodo. Controlla lo stato del cluster e del leader della coda. |
Per le code quorum, aggiungi le colonne leader e di appartenenza:
rabbitmqctl -p / list_queues name type leader members online messages_ready messages_unacknowledged consumers state
Questo è importante perché una coda può avere consumatori sani su un nodo mentre il leader si trova altrove, oppure una coda quorum può essere in attesa che un numero sufficiente di membri torni online.
Se l'elenco è lungo, filtra con gli strumenti shell standard:
rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged consumers state \
| awk '$2 > 0 || $3 > 0 || $4 == 0'
Verifica se il broker sta bloccando i publisher
rabbitmqctl status
rabbitmq-diagnostics alarms
Gli allarmi di memoria e disco non significano che la coda sia configurata male, ma spiegano molti incidenti in cui "non si muove nulla". Quando RabbitMQ solleva un allarme di memoria o di spazio libero su disco, può bloccare le connessioni di pubblicazione. I consumatori potrebbero ancora drenare i messaggi, quindi il sintomo visibile potrebbe essere irregolare: alcune code si riducono, altre smettono di ricevere nuovo lavoro e i publisher vanno in timeout.
Controlla anche i listener e la salute del nodo:
rabbitmq-diagnostics ping
rabbitmq-diagnostics listeners
rabbitmq-diagnostics check_running
rabbitmq-diagnostics check_local_alarms
Ispeziona i consumatori senza indovinare
list_connections ti dice chi è connesso. list_channels ti dice se quelle connessioni hanno aperto canali e quanto lavoro stanno gestendo.
rabbitmqctl list_connections name user peer_host peer_port state channels recv_oct send_oct
rabbitmqctl list_channels connection name number consumer_count messages_unacknowledged prefetch_count state
I pattern utili sono semplici:
- Nessuna connessione dall'host previsto: l'applicazione è giù, non riesce a risolvere il broker, non riesce ad autenticarsi o si sta connettendo a un altro ambiente.
- La connessione esiste, ma nessun canale: il client si è connesso e poi ha fallito prima di dichiarare o consumare.
- I canali esistono, ma
consumer_countè0: l'app potrebbe solo pubblicare o la sottoscrizione del consumatore è fallita. messages_unacknowledgedè alto su un canale: quel consumatore ha lavoro in memoria e non sta restituendo gli ack rapidamente.
Se usi connessioni con nome, includi connection_name nella configurazione del tuo client. Una riga come 10.42.8.17:52344 -> 10.42.1.20:5672 è meno utile di billing-worker-7.
Verifica i binding prima di incolpare i consumatori
Quando una coda è vuota ma l'applicazione dice di aver pubblicato messaggi, l'instradamento è il prossimo posto da controllare.
rabbitmqctl -p / list_exchanges name type durable auto_delete internal arguments
rabbitmqctl -p / list_bindings source_name source_kind destination_name destination_kind routing_key arguments
Un exchange diretto richiede una corrispondenza esatta della routing key. Un exchange topic usa * per una parola e # per zero o più parole. Un exchange fanout ignora le routing key. Se l'exchange non ha binding corrispondente e nessun exchange alternativo, il messaggio non è instradabile. Non è segretamente in attesa da qualche parte.
Per la conferma lato publisher, usa la pubblicazione obbligatoria e gestisci i messaggi restituiti nel client. Sul lato broker, l'interfaccia di gestione e le metriche sono solitamente migliori di rabbitmqctl per le velocità, ma list_bindings è sufficiente per cogliere gli errori comuni: vhost sbagliato, exchange sbagliato, routing key scritta male o una coda associata al vecchio exchange dopo una distribuzione.
Campiona un messaggio in sicurezza
Non esiste un comando rabbitmqctl queue_get generale in RabbitMQ moderno. Usa il plugin di gestione tramite rabbitmqadmin o l'API HTTP. Fallo con attenzione: a seconda della modalità di ack, ottenere messaggi può rimuoverli o riaccodarli.
rabbitmqadmin -V / get queue=orders.pending count=3 ackmode=ack_requeue_true
Usalo per rispondere a domande mirate: il payload è JSON valido, il tipo di messaggio è quello che il consumatore si aspetta, manca un'intestazione richiesta, la routing key è quella che il team di produzione ha detto che fosse? Non usarlo come strumento di ispezione di massa su una coda di produzione occupata.
Cerca il movimento dei dead-letter
L'elaborazione ritardata spesso si manifesta come una coda di dead-letter che cresce silenziosamente.
rabbitmqctl -p / list_queues name messages_ready messages_unacknowledged arguments policy
rabbitmqctl -p / list_bindings source_name destination_name routing_key arguments \
| grep -E 'dead|dlx|retry|parking'
Gli argomenti della coda come x-dead-letter-exchange, x-dead-letter-routing-key, x-message-ttl, x-max-length e x-overflow cambiano dove vanno i messaggi quando scadono, vengono rifiutati o raggiungono i limiti di lunghezza. Se l'applicazione riprova tramite dead-lettering attraverso code di ritardo, un binding errato può creare un ciclo. Il sintomo sembra "messaggi ritardati", ma il vero problema è che i messaggi ciclano tra le code invece di raggiungere una coda di elaborazione finale o una coda di parcheggio.
Una sequenza di comandi pratica
Quando qualcuno segnala "gli ordini sono bloccati", di solito eseguo questa sequenza:
rabbitmq-diagnostics ping
rabbitmq-diagnostics check_local_alarms
rabbitmqctl -p orders list_queues name type messages_ready messages_unacknowledged consumers state
rabbitmqctl list_connections name user peer_host state channels
rabbitmqctl list_channels connection consumer_count messages_unacknowledged prefetch_count state
rabbitmqctl -p orders list_bindings source_name destination_name routing_key arguments
Se messages_ready è alto e consumers è zero, vai alla distribuzione del consumatore. Se messages_unacknowledged è alto, vai ai log del consumatore e alle impostazioni di prefetch. Se la coda è vuota ma i publisher riportano successo, ispeziona i binding e le conferme del publisher. Se gli allarmi sono attivi, risolvi la pressione sulle risorse del broker prima di inseguire la logica dell'applicazione. Questo mantiene l'indagine ancorata a ciò che il broker sta effettivamente facendo.