Va bene se alcuni messaggi sono duplicati o persi? Quando il client JMS si connette al broker JMS sulla rete, ci sono tre fasi per ogni chiamata API.
- La chiamata API, inclusi i dati dei messaggi, viene trasmessa sul filo al broker.
- La chiamata API viene eseguita dal broker.
- Il codice risultato e tutti i dati dei messaggi vengono trasmessi al client.
Considerare il produttore per un minuto. Se la connessione viene interrotta nel primo passaggio, il broker non ha mai ricevuto il messaggio e l'app dovrà inviarlo di nuovo. Se la connessione viene interrotta nel terzo passaggio, il messaggio è stato inviato correttamente e l'invio di nuovo produrrebbe un messaggio duplicato. L'app non può dire la differenza tra questi e quindi l'unica scelta sicura è di inviare nuovamente il messaggio in caso di errore. Se la sessione viene trasferita, il messaggio può essere risentito in tutti i casi in modo sicuro, perché se l'originale è stato inoltrato al broker, verrà eseguito il rollback.
Considerare il consumatore. Se la connessione viene persa nel terzo passaggio, il messaggio viene eliminato dalla coda ma non viene mai restituito al client. Ma se la sessione viene trasferita, il messaggio verrà riconsegnato quando l'applicazione si riconnetterà.
Al di fuori delle transazioni c'è la possibilità di messaggi persi o duplicati. All'interno di una transazione esiste la stessa finestra di ambiguità ma è sulla chiamata COMMIT piuttosto che su PUT o GET. Con sessioni transate è possibile inviare o ricevere un messaggio due volte ma non perderne uno.
Il JMS spec riconosce questa finestra di ambiguità e fornisce le seguenti linee guida:
Se si verifica un guasto tra momento in cui un cliente si impegna il suo lavoro su una sessione e l' ritorna metodo commit, il client impossibile determinare se la transazione è stata confermata o annullato. La stessa ambiguità esiste quando si verifica un errore tra l'invio non transazionale di un messaggio PERSISTENT e il ritorno dal metodo di invio .
Spetta a un'applicazione JMS occuparsi di con questa ambiguità. In alcuni casi, ciò potrebbe causare la duplicazione dei messaggi da parte di un client per produrre .
Un messaggio che viene riconsegnato a causa del recupero della sessione non è considerato un messaggio duplicato .
Le sessioni JMS devono sempre essere gestite, ad eccezione dei casi in cui è davvero corretto perdere i messaggi. Se le sessioni vengono eseguite, è necessario disporre della sessione e della connessione per-thread a causa del modello di thread JMS.
Qualsiasi consiglio sugli impatti delle prestazioni sarebbe specifico del fornitore, ma in generale i messaggi persistenti al di fuori del punto di sincronizzazione vengono induriti su disco prima che la chiamata API ritorni. Ma una chiamata gestita può tornare prima che il messaggio persistente venga scritto sul disco a condizione che il messaggio venga mantenuto prima che COMMIT restituisca. Se il fornitore ottimizza in base a ciò, è molto più performante scrivere diversi messaggi su disco e quindi eseguirne il commit in batch. Ciò consente al broker di ottimizzare scritture e svuotamenti del disco per blocco del disco anziché per messaggio. Il numero di messaggi da inserire nella transazione diminuisce con la dimensione del messaggio e oltre una determinata dimensione del messaggio si riduce a uno.
Se i messaggi di 20k sono relativamente piccoli (misurati in k e non in mb), probabilmente si desidera utilizzare sessioni transulate per thread e ottimizzare l'intervallo di commit.