Qualcuno può spiegare cosa sta succedendo dietro le quinte in un cluster RabbitMQ con più nodi e code in modo speculare quando si pubblica su un nodo slave?RabbitMQ comportamento delle code di mirroring e dei mirror dietro le quinte
Da quello che ho letto, sembra che tutte le azioni diverse da quelle pubblicate vadano solo al master e il master trasmette quindi l'effetto delle azioni agli schiavi (questo è dalla documentazione). Formando la mia comprensione significa che un consumatore consumerà sempre il messaggio dalla coda principale. Inoltre, se invio una richiesta a uno slave per il consumo di un messaggio, lo slave eseguirà un salto extra raggiungendo il master per il recupero di quel messaggio.
Ma cosa succede quando pubblico su un nodo slave? Questo nodo farà la stessa cosa di inviare prima il messaggio al master?
Sembra che ci siano così tanti salti in più quando si ha a che fare con gli schiavi, quindi sembra che potresti avere prestazioni migliori se conosci solo il master. Ma come gestisci il master failure? Allora uno degli schiavi sarà eletto padrone, quindi devi sapere dove connetterti?
Chiedere tutto questo perché stiamo usando il cluster RabbitMQ con HAProxy in primo piano, in modo da poter disaccoppiare la struttura del cluster dalle nostre app. In questo modo, ogni volta che un nodo viene terminato, l'HAProxy si reindirizzerà ai nodi viventi. Ma abbiamo problemi quando uccidiamo uno dei nodi del coniglio. La connessione a coniglio è permanente, quindi se fallisce, devi ricrearla. Inoltre, devi inviare nuovamente i messaggi in questo caso, altrimenti li perderai.
Anche con tutto questo, i messaggi possono ancora essere persi, perché potrebbero essere in transito quando uccido un nodo (in alcuni buffer, da qualche parte sulla rete, ecc.). Pertanto, è necessario utilizzare le transazioni o confermare l'editore, che garantisce la consegna dopo che tutti i mirror sono stati riempiti con il messaggio. Ma qui un altro problema. Potresti avere messaggi duplicati, perché il broker potrebbe aver inviato una conferma che non ha mai raggiunto il produttore (a causa di errori di rete, ecc.). Pertanto, le applicazioni consumer dovranno eseguire la deduplicazione o gestire i messaggi in arrivo in modo idempotente.
C'è un modo per evitarlo? O devo decidere se posso perdere un paio di messaggi rispetto alla duplicazione di alcuni messaggi?
Grazie, Paul. Sei un dio. Giusto per assicurarmi che prima di passare all'implementazione puoi per favore confermare questo: 1) Posso usare ancora usare HAProxy e l'editore conferma e non perderò alcun messaggio. Avrò messaggi duplicati, che devo rimuovere in qualche modo. Avrò problemi di prestazioni (dovuti al luppolo extra al master quando raggiungo gli schiavi), ma i miei dati saranno "a prova di proiettile". 2) Al fine di aumentare le prestazioni, creerò un servizio di monitoraggio, quindi invierò le mie richieste solo al master ogni volta, ma devo ancora occuparmi dei duplicati. Grazie. –
È ancora possibile utilizzare HAProxy, ma si incorre in ulteriori passaggi di rete con una configurazione round robin. Se vuoi raggiungere anche il bilanciamento del carico, leggi questo: http://insidethecpu.com/2014/11/17/load-balancing-a-rabbitmq-cluster/ È molto improbabile che tu abbia messaggi duplicati.Penso che l'impostazione della proprietà message-ttl sia sufficiente per rimuovere i duplicati, sebbene l'aggiunta di un reference-tag, come ho detto, risolverà il problema. Rilascerò una libreria RabbitMQ in C# che raggiunge quanto sopra, a breve. Continua a monitorare il mio blog per gli aggiornamenti. –
In realtà ho finito per avere messaggi duplicati. Ho eseguito un test un paio di volte pubblicando 10000 messaggi su un cluster Rabbit a 2 nodi. Ho ucciso un nodo e ho ricevuto 10011-10012 messaggi. Una delle mie API di consumo è idempotente, quindi il risultato finale era ok. Molte grazie. –