2009-02-05 13 views
7

Sto attraversando un periodo difficile per capire come progettare l'ultimo pezzo del mio sistema. Attualmente sto utilizzando un server Tomcat con un servlet che risponde alle richieste dei client. Ogni richiesta a sua volta aggiunge un messaggio di elaborazione a una coda asincrona (probabilmente userò JMS tramite Spring o più probabilmente Amazon SQS).Qual è il modo migliore per elaborare una coda asincrona continuamente in Java?

La sequenza degli eventi è questo:

lato invio:
1. Prendere una richiesta del client
2. Aggiungere alcuni dati in un DB relativi a questa richiesta con un ID univoco
3. Aggiungere un oggetto messaggio che rappresenta la richiesta alla coda di messaggi

Ricezione lato:
1. Estrarre un nuovo oggetto messaggio dalla coda
2. Separa l'oggetto e grab alcune informazioni da un sito web basate sulle informazioni contenute nell'oggetto msg.
3. Invia un avviso e-mail
4. aggiornare la mia riga DB (stesso ID univoco) con le informazioni relative al completamento dell'operazione per questa richiesta.

Sto avendo un difficile capire come affrontare correttamente il lato ricevente. Da un lato, posso probabilmente creare un semplice programma java che avvio dalla riga di comando che seleziona ogni elemento in coda e lo elabora. È sicuro? Ha più senso avere quel programma in esecuzione come un altro thread all'interno del contenitore Tomcat? Non voglio farlo in serie, il che significa che il destinatario deve essere in grado di elaborare diversi oggetti alla volta - utilizzando più thread. Voglio che questo sia sempre attivo, 24 ore al giorno.

Quali sono alcune opzioni per la costruzione del lato ricevente?

+0

Nel caso qualcuno fosse interessato a ciò che alla fine ho finito di fare. Ho usato SQS di Amazon e ho un client java (utilizza la struttura a molla) che esegue il polling della coda. Quando trova un messaggio, lo elabora e torna in stato di attesa. Potrei aggiungere il threading del quarzo, perché ora ho appena avviato più processi. – Ish

+0

Sto affrontando un problema simile. Mi piacerebbe sapere come è stato implementato il client Java. Spero che non venga eseguito in un ciclo infinito mentre si raggruppa per il messaggio? –

risposta

3

"Da un lato probabilmente posso creare un semplice programma java che avvio dalla riga di comando che preleva ogni elemento in coda e lo elabora. È sicuro?"

Cosa non è sicuro? Funziona alla grande.

"Ha più senso avere quel programma in esecuzione come un altro thread all'interno del contenitore Tomcat?"

Solo se Tomcat ha molto tempo libero per gestire l'elaborazione in background. Spesso, questo è il caso - avete tempo libero per fare questo tipo di elaborazione.

Tuttavia, i thread non sono ottimali. I thread condividono le risorse I/O comuni e il thread in background potrebbe rallentare il front-end.

È meglio disporre di una coda JMS tra il front-end "porta 80" e un processo di back-end separato. Il processo di back-end inizia, si collega alla coda, recupera ed esegue le richieste. Il processo di back-end può (se necessario) essere multi-thread.

0

Ho fatto questo genere di cose ospitando il ricevitore in un app server, weblogic nel mio caso, ma anche Tomcat funziona bene. Non eseguire il polling della coda, utilizzare un modello basato su eventi. Questo potrebbe essere codificato a mano o potrebbe essere un servizio web basato sui messaggi. Se l'aggiornamento del database è idempotente, è possibile aggiornare il database e inviare l'e-mail, quindi emettere il commit sulla coda. Non è un problema avere diversi thread letti tutti dalla stessa coda.

Ho usato varie soluzioni JMS, incluso tibco, activemq (prima di apache incluso) e joram. Joram era la soluzione opensource più affidabile, ma potrebbe essere cambiata ora che fa parte dell'apache.

+0

Puoi spiegare come implementare un modello basato su eventi? –

+0

Dai un'occhiata a http://docs.oracle.com/cd/E13222_01/wls/docs90/jms/implement.html#1188496, la sezione intitolata "Ricevere messaggi in modo asincrono". –

1

Se stai già utilizzando Spring, controlla DefaultMessageListenerContainer. Permette di creare un bean guidato da POJO. Può essere utilizzato da un contenitore di applicazioni esistente (il file WAR) o come processo separato.

+0

In questo caso il consumatore esegue continuamente il polling della coda o viene avvisato in qualche modo? – Ish

+0

Sono abbastanza sicuro che i sondaggi DefaultMessageListenerContainer. La cosa bella è che nasconde il problema del polling/notifica da te. Devi solo implementare un jms MessageListener e fare tutto il lavoro che devi fare. –

2

Se si utilizza JMS, perché si inseriscono le attività in un DB?

È possibile utilizzare una coda duratura in JMS. Ciò manterrebbe le attività, anche se il broker JMS muore, fino a quando non vengono riconosciute. Puoi avere intermediari ridondanti in modo che se un broker muore, il secondo subentra automaticamente. Questo potrebbe essere più affidabile rispetto all'utilizzo di un singolo DB.

+0

Perché recupererò alcune informazioni dal sito Web di destinazione e le inserirò accanto alla riga nel DB. Queste informazioni dovranno quindi essere recuperate da un cliente in un secondo momento. Non sto realmente usando db per la ridondanza tanto quanto per l'archiviazione dei dati per il successivo recupero. – Ish

Problemi correlati