2014-06-08 20 views
19

Dopo che l'utente riceve un messaggio, l'utente/operatore esegue alcune convalide e quindi chiama il servizio web. In questa fase, se si verifica un errore o se la convalida fallisce, vogliamo che il messaggio ritorni alla coda da cui era originariamente consumato.Come riaccodare i messaggi in RabbitMQ

Ho letto la documentazione di RabbitMQ. Ma sono confuso dalle differenze tra i metodi reject, nack e cancel.

risposta

44

Risposta breve:

Per riaccodare messaggio specifico si può scegliere sia basic.reject o basic.nack con multiple flag impostato su false.

basic.consume La chiamata può anche comportare la riconsegna dei messaggi se si sta utilizzando il riconoscimento del messaggio e ci sono messaggi non riconosciuti sul consumatore in un momento specifico e l'uscita del consumatore senza accedervi.

basic.recover ricollegherà tutti i messaggi non sincronizzati su un canale specifico.

Risposta lunga:

basic.reject e basic.nack entrambi serve a stesso scopo - goccia o un messaggio riaccodamento che non può essere gestita da specifica del consumatore (al momento opportuno, a determinate condizioni o affatto). La principale differenza tra loro è che basic.nack supporta l'elaborazione di messaggi in blocco, mentre lo basic.reject no.

Questa differenza descritto nel Negative Acknowledgements articolo sul sito ufficiale RabbitMQ web:

La specifica AMQP definisce il metodo basic.reject che consente ai clienti di respingere singoli, i messaggi consegnati, istruendo il broker a uno disfarsene o riaccodare. Sfortunatamente, basic.reject non fornisce supporto per il riconoscimento negativo dei messaggi in blocco.

Per risolvere questo problema, RabbitMQ supporta il metodo basic.nack che fornisce tutte le funzionalità di basic.reject pur consentendo anche per il trattamento di massa di messaggi.

Per rifiutare i messaggi in blocco, i client impostano il flag multiple del metodo basic.nack su true. Il broker rifiuterà quindi tutti i messaggi consegnati non confermati fino a includere il messaggio specificato nel campo delivery_tag del metodo basic.nack. A tale riguardo, basic.nack integra la semantica di riconoscimento collettivo di basic.ack.

nota, tale metodo è basic.nack estensione RabbitMQ-specifico, mentre basic.reject metodo fa parte di AMQP specifica 0.9.1.

Per quanto riguarda il metodo basic.cancel, è stato utilizzato per notificare al server che il client interrompe il consumo di messaggi. Si noti che il client può ricevere un numero di messaggi arbitrari tra il metodo basic.cancel inviando un destinatario alla risposta cancel-ok. Se il messaggio di conferma viene utilizzato dal client e contiene messaggi non riconosciuti, questi verranno spostati nella coda da cui originariamente erano stati utilizzati.

basic.recover presenta alcune limitazioni in RabbitMQ: it - basic.recover with requeue=false - basic.recover synchronicity

Oltre a errata, according to RabbitMQ specsbasic.recover ha il supporto parziale

nota circa (Recupero con riaccodamento = false non è supportato.) basic.consume:

Quando basic.consume avviato senza auto-ack (no­ack=false) e ci sono alcuni messaggi in attesa di messaggi non sincronizzati, quindi quando l'utente viene annullato (muore, errore fatale, eccezione, qualunque cosa) i messaggi in sospeso saranno riconsegnati. Tecnicamente, i messaggi in sospeso non verranno elaborati (nemmeno con lettere senza risposta) finché i consumatori non li rilasciano (ack/nack/reject/recover). Solo dopo verranno elaborati (ad esempio deadletter).

Per esempio, diciamo che abbiamo posto originariamente 5 messaggio consecutive:

Queue(main) (tail) { [4] [3] [2] [1] [0] } (head) 

E poi consumano 3 di loro, ma non li ACK e quindi annullare consumatori. Avremo questa situazione:

Queue(main) (tail) { [4] [3] [2*] [1*] [0*] } (head) 

cui stella (*) osserva che redelivered bandiera impostato su true.

Assumiamo di avere la situazione con il set di scambio dead-lettere e una coda per morti-letterato messaggi

Exchange(e-main)         Exchange(e-dead) 
    Queue(main){x-dead-letter-exchange: "e-dead"}  Queue(dead) 

e assumere abbiamo posto 5 messaggio con expire proprietà impostata a 5000 (5 sec):

Queue(main) (tail) { [4] [3] [2] [1] [0] } (head) 
Queue(dead) (tail) { }(head) 

e poi consumare 3 messaggio dalla coda di main e tenerli per 10 secondi:

Queue(main) (tail) { [2!] [1!] [0!] } (head) 
Queue(dead) (tail) { [4*] [3*] } (head) 

dove il punto esclamativo (!) sta per messaggio non registrato. Tali messaggi non possono essere consegnati a nessun consumatore e normalmente non possono essere visualizzati nel pannello di gestione. Ma cerchiamo di annullare consumatori, ricordate, che continuano a detenere 3 UN-completamente riscontrato un messaggio:

Queue(main) (tail) { } (head) 
Queue(dead) (tail) { [2*] [1*] [0*] [4*] [3*] } (head) 

Quindi, ora che 3 messaggi che era nella testa ha messo di nuovo a coda originale, ma come si è posta TTL per-messaggio, sono letteralmente muti alla coda della coda di lettere morte (certo, attraverso lo scambio di lettere morte).

P.S .:

Consumare messaggio alias di ascolto per nuovo è in qualche modo diverso da accesso coda diretta (ottenere uno o più messaggi, senza prendersi cura degli altri). Vedere la descrizione del metodo basic.get per ulteriori informazioni.

+0

Se basic.nack è esattamente come basic.reject ma supporta l'elaborazione di messaggi bulk, quando è basic.reject preferito su basic.nack? Perché non si usa solo basic.nack in tutte le situazioni? – Glide

+0

['basic.nack'] (https://www.rabbitmq.com/nack.html) è l'estensione specifica per RabbitMQ. – pinepain

+0

di "estensione specifica RabbitMQ" intendi fuori dall'estensione non utilizzata? Significato se ho usato Spring AMQP per l'integrazione con RabbitMQ, quindi non posso usare basic.nack? – Glide

Problemi correlati