2009-02-05 9 views
7

Es fällt mir schwer, herauszufinden, wie ich das letzte Stück meines Systems gestalten soll. Zur Zeit betreibe ich einen Tomcat-Server mit einem Servlet, das auf Client-Anfragen reagiert. Jede Anfrage fügt wiederum eine Verarbeitungsnachricht zu einer asynchronen Warteschlange hinzu (ich werde wahrscheinlich JMS über Spring oder wahrscheinlicher Amazon SQS verwenden).Was ist der beste Weg, um eine asynchrone Warteschlange kontinuierlich in Java zu verarbeiten?

Die Abfolge der Ereignisse ist dies:

Senden Seite: mit einer eindeutigen ID
1. eine Client-Anforderung einige Daten in einem DB zu dieser Anfrage
3. ein In Zusammenhang Nehmen
2. Fügen Nachrichtenobjekt diese Anfrage an die Nachrichtenwarteschlange repräsentiert

Empfangsseite:
1. eine neue Nachricht Objekt Ziehen aus der Warteschlange
2. Abwickelwerkzeug das Objekt und Halte einige Informationen von einer Website basierend auf Informationen, die im msg-Objekt enthalten sind.
3. Senden Sie eine E-Mail-Benachrichtigung
4. Aktualisieren Sie meine DB-Zeile (gleiche eindeutige ID) mit der Information, dass Operation für diese Anfrage abgeschlossen wurde.

Ich habe eine harte herauszufinden, wie man richtig mit der Empfangsseite umgehen. Auf der einen Seite kann ich wahrscheinlich ein einfaches Java-Programm erstellen, das ich von der Befehlszeile aus starte, die jedes Element in der Warteschlange auswählt und verarbeitet. Ist das sicher? Macht es mehr Sinn, das Programm als einen anderen Thread im Tomcat-Container laufen zu lassen? Ich möchte das nicht seriell machen, dh das empfangende Ende sollte in der Lage sein, mehrere Objekte gleichzeitig zu verarbeiten - mit mehreren Threads. Ich möchte, dass dies 24 Stunden am Tag läuft.

Was sind einige Optionen zum Aufbau der Empfangsseite?

+0

Falls jemand interessiert ist, was ich schließlich getan habe. Ich habe Amazons SQS benutzt und habe einen Java-Client (benutzt das Spring-Framework), der die Warteschlange abfragt. Wenn es eine Nachricht findet, verarbeitet es sie und geht in den Wartezustand zurück. Ich könnte Quarz-Threading hinzufügen, für den Moment starte ich einfach mehrere Prozesse. – Ish

+0

Ich stehe vor einem ähnlichen Problem. Ich würde gerne wissen, wie der Java Client implementiert wurde. Ich hoffe, es läuft nicht in einer unendlichen While-Schleife und Pools für die Nachricht? –

Antwort

3

"Auf der einen Seite kann ich wahrscheinlich ein einfaches Java-Programm erstellen, das ich von der Befehlszeile aus starte, die jedes Element in der Warteschlange auswählt und verarbeitet. Ist das sicher?"

Was ist daran unsicher? Es funktioniert großartig.

"Ist es sinnvoller, das Programm als einen anderen Thread im Tomcat-Container laufen zu lassen?"

Nur wenn Tomcat viel freie Zeit hat, Hintergrundverarbeitung zu verarbeiten. Oft ist diese der Fall - Sie haben Freizeit, diese Art der Verarbeitung zu tun.

Die Gewinde sind jedoch nicht optimal. Threads teilen sich gemeinsame E/A-Ressourcen, und Ihr Hintergrund-Thread kann das Front-End verlangsamen.

Besser ist eine JMS-Warteschlange zwischen dem Frontport "Port 80" und einem separaten Back-End-Prozess. Der Back-End-Prozess wird gestartet, stellt eine Verbindung mit der Warteschlange her, ruft die Anforderungen ab und führt sie aus. Der Backend-Prozess kann (falls erforderlich) multi-threaded sein.

0

Ich habe so etwas getan, indem ich den Empfänger in einem App-Server gehostet habe, Weblogic in meinem Fall, aber Tomcat funktioniert auch gut. Abfragen Sie die Warteschlange nicht ab, verwenden Sie ein ereignisbasiertes Modell. Dies könnte handcodiert sein, oder es könnte ein nachrichtengesteuerter Webdienst sein. Wenn das Datenbankupdate idempotent ist, können Sie die Datenbank aktualisieren und die E-Mail senden und anschließend die Festschreibung in der Warteschlange durchführen. Es ist kein Problem, mehrere Threads zu haben, die alle aus derselben Warteschlange lesen.

Ich habe verschiedene JMS-Lösungen, einschließlich tibco, activemq (vor Apache subsumiert es) und Joram. Joram war die zuverlässigere Open Source-Lösung, aber das könnte sich jetzt geändert haben, da es Teil von Apache ist.

+0

Können Sie erklären, wie ein ereignisbasiertes Modell implementiert wird? –

+0

Werfen Sie einen Blick auf http://docs.oracle.com/cd/E13222_01/wls/docs90/jms/implement.html#1188496, den Abschnitt mit dem Titel "Nachrichten asynchron empfangen". –

1

Wenn Sie bereits Spring verwenden, lesen Sie DefaultMessageListenerContainer. Es ermöglicht Ihnen, eine POJO Message Driven Bean zu erstellen. Dies kann innerhalb eines vorhandenen Anwendungscontainers (Ihrer WAR-Datei) oder als separater Prozess verwendet werden.

+0

In diesem Fall fragt der Konsument die Warteschlange ständig ab oder wird er irgendwie benachrichtigt? – Ish

+0

Ich bin ziemlich sicher, dass der DefaultMessageListenerContainer abfragt. Das Schöne daran ist, dass es das Umfrage-/Benachrichtigungsproblem von Ihnen verbirgt. Sie implementieren einfach einen jms MessageListener und tun alles, was Sie tun müssen. –

2

Wenn Sie JMS verwenden, warum platzieren Sie die Aufgaben in einer Datenbank?

Sie können eine dauerhafte Warteschlange in JMS verwenden. Dies würde Aufgaben behalten, selbst wenn der JMS-Broker stirbt, bis sie bestätigt werden. Sie können redundante Broker haben, so dass wenn ein Broker stirbt, der zweite automatisch übernimmt. Dies könnte zuverlässiger sein als die Verwendung einer einzelnen DB.

+0

Weil ich einige Informationen von der Zielwebsite abrufen und neben der Zeile in der Datenbank platzieren werde. Diese Information muss dann zu einem späteren Zeitpunkt von einem Client abgerufen werden. Ich verwende nicht wirklich db für Redundanz so viel wie für die Speicherung von Daten für späteren Abruf. – Ish

Verwandte Themen