2012-10-30 20 views
5

Ho un caso di utilizzo di pubblicazione-sottoscrizione in cui desidero bloccare il lato di pubblicazione fino a quando ciascuno dei sottoscrittori conferma di aver completato la gestione del messaggio inviato dal publisher.Perché Channel.waitForConfirmsOrDie non è bloccato?

I (erroneamente?) Presupponevo che potrei usare RabbitMQ e il suo metodo Channel.waitForConfirmsOrDie del client amqp Java come parte della mia soluzione. Il problema è che non ho trovato un caso in cui waitForConfirmsOrDie bloccherà effettivamente.

Secondo il javadocs, waitForConfirmsOrDie si suppone che:

Attendere fino a quando tutti i messaggi pubblicati dopo l'ultima chiamata sono stati sia ack'd o nack'd dal broker. Se uno dei messaggi non era presente, waitForConfirmsOrDie genererà un'eccezione IOException. Se chiamato su un canale non confermato, verrà restituito immediatamente.

Per verificare che questo metodo funzioni davvero, ho iniziato con this example code from the RabbitMQ website.

Il codice di esempio crea un editore e un consumatore, ciascuno sul proprio thread separato. Quindi l'editore invia i messaggi allo scambio mentre il consumatore consuma i messaggi. Sembra che l'editore debba bloccare fino a quando tutti i messaggi non vengono ack tramite la sua chiamata a waitForConfirmsOrDie().

Questo codice di esempio sembrava corrispondere perfettamente con quello che stavo cercando di fare. Ma non sembra funzionare come pensavo. Infatti, se, nel thread del consumer, disattivo i messaggi di auto-acking, waitForConfirmsOrDie() restituisce immediatamente.

ho spento ACK automatico, semplicemente cambiando uno false a true: ch.queueDeclare(QUEUE_NAME, false, false, false, null); diventa ch.queueDeclare(QUEUE_NAME, true, false, false, null); (2 ° ARG falso invece di vero). Credo che questo significhi che gli utenti non debbano più essere inviati dal consumatore.

Quindi cosa fa waitForConfirmsOrDie() in realtà? Quando bloccherebbe?

Se waitForConfirmsOrDie non fa quello che voglio, c'è un modo per far sì che un editore attenda fino a quando tutti gli abbonati non accetteranno un messaggio prima di procedere?

risposta

7

Per quanto ho capito, queste chiamate non dovrebbero attendere la conferma da parte del consumatore. Lo scopo dei metodi waitForConfirms* è assicurarsi che il messaggio sia stato consegnato al broker e per fornire un tipo di notifica di consegna/errore di base. In altre parole, il messaggio non scomparirà senza che la notifica produca nel caso in cui uno dei nodi rmq (o anche tutti i nodi) non sia riuscito/non disponibile.

È possibile visualizzare questa eccezione in azione se si disconnette o si disattiva rmq prima della chiamata basicPublish.

Problemi correlati