Sostituzione del polling del database con le code di messaggistica

3

Abbiamo un lavoro in background (java batch) che ascolta / legge da un MQ e persiste un messaggio nel database (tabella locale). Quindi un trigger invia questo messaggio in una tabella di accodamento in stato di ATTESA. Il mio programma di polling (multithreaded in java) esegue sondaggi continui per i record WAITING, li preleva e li invia al consumatore appropriato (programma java). Anche i messaggi dello stesso tipo devono essere elaborati in modo sincrono. (stesso numero d'ordine, ma entrambi arrivano all'N ° minuto. È necessario completarlo prima che inizi un altro) Tuttavia in questo caso a causa del polling del database c'era la possibilità che lo stesso record potesse essere prelevato da due thread che ha causato un problema, quindi abbiamo messo il polling come sincronizzato che ora si traduce in deadlock.

Come posso rimuovere questo polling del database e utilizzare un meccanismo o code basato su eventi che sarebbe possibile anziché il polling del database e preservare anche la sincronizzazione.

Edit-- L'ulteriore elaborazione dei messaggi comprende 4 attività di natura asincrona, ma tutte le attività devono essere completate prima di elaborare il secondo messaggio dello stesso tipo (orderid). Il processo padre deve essere sincrono e il figlio asincrono. Saranno necessarie 2 code per lo stesso?

    
posta Akhil 23.11.2017 - 07:16
fonte

2 risposte

1

L'ho fatto prima di usare Kafka. Avere il programma che persiste ogni record, inviare un messaggio su una seconda coda dopo l'inserimento riesce. Il tuo consumatore può quindi eseguire il polling dei messaggi sulla seconda coda e fare il suo lavoro. Il tuo MQ dovrebbe essere in grado di gestire più utenti che leggono dalla stessa coda e dall'elaborazione in ordine.

Per quanto riguarda la tua modifica ... Dipende da come il tuo genitore consumatore comunica ai bambini. È possibile rimanere con 2 code se tutti i codici utente si trovano nella stessa JVM. Il consumatore padre dovrebbe agire come il sincronizzatore: estrarrà i messaggi in sequenza, quindi genererà le attività secondarie come thread per eseguire il loro bit asincrono, quindi una volta che tutti i bambini sono stati completati, può estrarre l'ordine successivo. I bambini possono comunicare il loro stato di completamento al genitore tramite callback, oppure il genitore fa un thread join sui figli.

Se genitore e figli sono in esecuzione in JVM separate, allora dovresti considerare un altro metodo di comunicazione. In questo caso. potrebbe essere utilizzata una terza coda (che tutti i bambini usano per comunicare i loro stati). Ho fatto questo anche con i callback API al genitore quando il genitore ha quell'abilità.

In ogni caso, il genitore deve attendere tutti gli stati di completamento prima di estrarre un altro messaggio di ordine dalla seconda coda. Dovresti anche avere un modo di timeout e avvisarti se i bambini impiegano più tempo del previsto.

    
risposta data 23.11.2017 - 12:06
fonte
3

Suggerirei che la lettura del programma dal MQ invierebbe il messaggio direttamente al consumatore, ignorando completamente il database. Alla fine, il messaggio può anche essere inserito nel database per la persistenza e la cronologia.

In alternativa, questo programma può inserire il messaggio nel database e inviare eventi al programma consumer con l'id della riga da utilizzare, preservando il comportamento sincrono.

    
risposta data 23.11.2017 - 11:05
fonte

Leggi altre domande sui tag