Effektive JMS-Verarbeitung

8

Wir haben eine JMS-Warteschlange, die eine sehr große Anzahl von Nachrichten empfängt.

Der Listener muss die Nachricht in der Datenbank mit einer Datenbanktransaktion speichern und anschließend die JMS-Transaktion festschreiben.

Also wie kann ich es effektiver machen, wo ich nicht Datenbank & Amp; JMS Commit für jede Nachricht.

    
changed 08.03.2011, 22:33
quelle

3 Antworten

6

Die Voraussetzung für asynchrone Nachrichtenübertragung, insbesondere bei Verwendung einer MDB, ist, dass jede Nachricht atomar ist. Das heißt, das Ergebnis der Verarbeitung einer einzelnen Nachricht soll unabhängig vom Ergebnis der Verarbeitung einer anderen Nachricht sein. Die ideale Lösung für Ihr Problem wird diese Atomizität von Nachrichten erhalten.

Wenn Sie mehrere Nachrichten in derselben Arbeitseinheit verarbeiten würden, würden Sie diese Atomarität verlieren. Angenommen, Sie haben beschlossen, alle 25 Nachrichten zu synchronisieren. Wenn die 25. Nachricht einen Fehler aufwies, z. B. ein Codepagekonvertierungsproblem, das verhinderte, dass sie aus der Warteschlange abgerufen wurde, wurde der gesamte Nachrichtenstapel zurückgesetzt. Sie würden dann alle erneut geliefert werden. Die Anzahl der Rücklieferungen für die Nachrichten würde mit jedem Lese- / Rücksetzzyklus zunehmen. Sobald die Anzahl der erneuten Zustellungen den auf Ihrem App-Server festgelegten Schwellenwert überschritten hat, werden alle 25 Nachrichten je nach Konfiguration verworfen oder erneut in die Warteschlange aufgenommen. Je größer der Stapel ist, desto mehr Nachrichten sind möglicherweise in einer Fehlersituation betroffen, da der gesamte Stapel zusammenlebt oder stirbt. Setzen Sie Ihre Batch-Größe auf 100 und 100 Nachrichten sind im Falle einer einzelnen Giftmeldung gefährdet.

Eine alternative Lösung besteht darin, viele Verarbeitungs-Threads in Ihrer MDB zu berücksichtigen. Mit JMS können Sie viele Sitzungen unter der gleichen Verbindung erstellen. Jede Sitzung kann ihre eigene Arbeitseinheit verwalten, daher kann jede Sitzung unabhängig eine XA-Transaktion starten, eine Nachricht abrufen, die Datenbank aktualisieren und dann die Transaktion festschreiben. Wenn eine Nachricht fehlerhaft ist, ist nur diese Nachricht und Datenbankaktualisierung betroffen.

Es gibt Ausnahmen. Wenn beispielsweise ein großer Stapel verarbeitet wird und die Nachrichten alle vom selben Hersteller stammen, ist es üblich, etwas anderes als eine MDB zu verwenden, um viele Nachrichten abzurufen und viele Zeilen unter derselben Arbeitseinheit zu aktualisieren. Wenn die Nachrichten sequenzabhängig sind, ist eine parallele Verarbeitung ebenfalls nicht möglich, da sie die Sequenz nicht beibehalten würde. Aber auch hier sind sequenzabhängige Nachrichten nicht atomar. Auch hier ist eine MDB nicht die ideale Lösung.

Abhängig von Ihrem Transportanbieter kann die Anzahl der unterstützten Threads nur durch den Speicher begrenzt sein. WebSphere MQ kann zum Beispiel problemlos Hunderte von gleichzeitigen Getter-Threads in einer Warteschlange verarbeiten. Überprüfen Sie die Optimierung für die MDB-Konfiguration Ihres App-Servers, um zu sehen, wie viele Threads hochgefahren werden können, und vergewissern Sie sich, dass Ihr Transport die Last verarbeiten kann. Dann spielen Sie ein bisschen herum, um die optimale Anzahl von Threads zu finden. Die Performance wird dramatisch ansteigen, wenn die Threads von eins, aber nur bis zu einem Punkt zunehmen. Über diesen Punkt hinaus sehen Sie im Allgemeinen ein Plateau, dann einen Rückgang, da der Thread-Management-Overhead die Leistungsgewinne ausgleicht. Wo der swe3et-Spot liegt, hängt davon ab, wie stark der Messaging-Broker geladen ist und ob er am meisten von CPU, Speicher, Festplatte oder Netzwerk abhängig ist.

    
T.Rob 09.03.2011, 02:29
quelle
8

Mach es nicht bei jeder Nachricht, mach es in Batches. JMS unterstützt Transaktionen genau wie Ihre Datenbank. Starten Sie eine JMS-Transaktion, lesen Sie N Nachrichten. Starten Sie die DB-Transaktion, fügen Sie N Nachrichten ein. Commit zu JMS, Commit zu DB.

Dies führt offensichtlich ein Fenster ein, in dem ein Rennen stattfinden kann (es kommt zu einem Absturz zwischen den beiden Commits). Das hast du jetzt, aber nur für eine einzelne Nachricht. Wenn Sie dieses Problem lösen wollen, müssen Sie sich entweder XA-Transaktionen ansehen (zweistufiges Commit) oder zumindest eine Art Duplikaterkennung. Schauen Sie sich für einige Intro an: Ссылка

    
Brian Roach 08.03.2011 22:41
quelle
0

Hier ist ein JMS-Prozessor, der Nachrichten aus einer Warteschlange nimmt, sie zu einer Liste hinzufügt und zu einer anderen Warteschlange zurückschiebt. Sie können einstellen, wie die Werte in den jeweiligen Methoden gelesen und aggregiert werden:

%Vor%

Dies kann in einem separaten Thread gestartet werden und nur für immer ausgeführt werden:

%Vor%

Sie können dann aus den zusammengefassten Ergebnissen stapelweise an die Datenbank übergeben. Wenn Fehler auftreten, wird die Transaktion erneut versucht.

    
Staale 08.01.2016 13:12
quelle

Tags und Links