Threading

Nachrichtenverarbeitungsknoten und Parser müssen in einer Multi-Thread-Umgebung mit mehreren Instanzen arbeiten. Es können viele Knotenobjekte oder Parserobjekte, jedes mit beliebigen Syntaxelementen, vorhanden sein und viele Threads, die Methoden für diese Objekte ausführen. Das Nachrichtenbrokerdesign stellt sicher, dass ein Nachrichtenobjekt und alle Objekte, die es besitzt, nur von dem Thread verwendet werden, der die Nachricht im Verlauf des Nachrichtenflusses empfängt und verarbeitet.

Eine Instanz eines Nachrichtenflussverarbeitungsknotens wird von allen Threads, die den Nachrichtenfluss bedienen, in dem der Knoten definiert ist, gemeinsam genutzt. Eine Instanz eines Parser wird nur von einem einzigen Nachrichtenfluss-Thread verwendet.

Eine benutzerspezifische Erweiterung muss sich an dieses Modell halten und sollte die Verwendung von globalen Daten oder Ressourcen vermeiden, die Semaphoren erfordern, um den Zugriff über Threads hinweg zu serialisieren. Eine solche serielle Verarbeitung kann Leistungsengpässe verursachen.

Implementierungsfunktionen einer benutzerspezifischen Erweiterung müssen simultan verwendbar sein, und alle Funktionen, die sie aufrufen, müssen es ebenfalls sein. Alle Dienstprogrammfunktionen einer benutzerspezifischen Erweiterung sind vollständig simultan verwendbar.

Auch wenn eine benutzerspezifische Erweiterung bei Bedarf zusätzliche Threads erstellen kann, ist es entscheidend, dass derselbe Thread die Steuerung nach Abschluss einer Implementierungsfunktion an den Broker zurückgibt. Geschieht dies nicht, wird die Integrität des Brokers verletzt und sind unvorhersehbare Ergebnisse die Folge.

Ausführungsmodell

Beim Initialisieren einer Ausführungsgruppe werden der Laufzeitkomponente die geeigneten LIL-Dateien zur Verfügung gestellt. Der Laufzeitprozess der Ausführungsgruppe wird gestartet und ruft einen zugeordneten Konfigurationsthread auf. In der Ausführungsumgebung des Nachrichtenflusses ist der Nachrichtenfluss threadsicher. Sie können Nachrichtenflüsse in vielen Betriebssystemthreads gleichzeitig ablaufen lassen, ohne sich Gedanken über die serielle Verarbeitung machen zu müssen. Dieses Threading-Modell wird auch durch benutzerspezifische Knoten, die Sie implementieren, nicht beeinträchtigt. Beachten Sie die folgenden Punkte:
  • Eine an einen Nachrichtenfluss gesendete Nachricht wird nur von dem Thread verarbeitet, der sie empfangen hat. Während der Nachrichtenverarbeitung findet weder ein Thread- noch ein Kontextwechsel statt.
  • Datenstrukturen, auf die Nachrichtenflüsse zugreifen, sind nur für einen Einzelthread sichtbar. Diese Datenstrukturen existieren nur so lange, wie die Verarbeitung der Nachricht dauert.
  • Eine Einzelinstanz eines Nachrichtenflusses wird von allen Threads im Thread-Pool des Nachrichtenflusses gemeinsam genutzt. Dies steht insofern in Zusammenhang mit dem Verhalten eines Nachrichtenknotens, dass es keinen Status gibt.
  • Der Speicherbedarf einer Ausführungsgruppe wird nicht unverhältnismäßig beeinflusst, wenn Nachrichtenflüsse in mehreren Betriebssystemthreads ausgeführt werden.

Threading-Modell

Das folgende Beispiel eines Nachrichtenflusses soll Ihnen helfen, einige der Threading-Besonderheiten, die Sie beim Entwerfen und Implementieren eigener benutzerspezifischer Knoten beachten sollten, zu verstehen. Dazu wird ein benutzerspezifischer Empfangsknoten als Beispiel verwendet.

Ein Nachrichtenfluss kann so konfiguriert werden, dass er in mehreren Threads ausgeführt wird. Dies wird durch die Anzahl der Empfangsknoten im Nachrichtenfluss und durch den Wert der Eigenschaft 'additionalInstances' des Nachrichtenflusses festgelegt. Diese beiden Elemente bestimmen die maximale Kapazität des Thread-Pools, den der Nachrichtenfluss verwenden kann. Falls für Ihren Nachrichtenfluss bestimmte Verarbeitungsanforderungen gelten, die eine Einzelthreadverarbeitung erforderlich machen, müssen Sie deshalb sicherstellen, dass dies der Fall ist.

Eine typische Reihenfolge von Ereignissen zur Empfangsknotenverarbeitung sieht wie folgt aus:
  1. Erstellung von Empfangsknoten
  2. Anforderung eines Threads aus dem Thread-Pool
  3. Start des zugeordneten Threads in der Ausführungsmethode des Knotens
  4. Festschreibung der Konfiguration (bzw. Rekonfiguration)
  5. Ausführung des Initialisierungsprozesses im Kontext des Threads
  6. Thread stellt Verbindung mit Warteschlangenmanager des Brokers her
  7. Erstellung einer Nachrichtengruppe und eines Pufferobjekts
  8. Senden einer Anforderung zum Öffnen der Eingabewarteschlange (queue open) an den Warteschlangenmanager. Diese Warteschlange bleibt während der gesamten Lebensdauer des Threads geöffnet.
  9. Empfangsknoten läuft in eine Nachrichtenverarbeitungsschleife
  10. Nach dem Empfang einer Nachricht enthält der Datenpuffer Header und Hauptteil der Nachricht
  11. Nachrichtenobjekte werden erstellt und an die Gruppe des Threads angehängt
  12. Aktivierung der Threadzuteilung, wenn mehrere Threads angegeben sind
  13. Nachrichtendaten werden downstream weitergeleitet
Beachten Sie Folgendes:
  • Ihr Empfangsknoten implementiert das ausgewählte Threading-Modell des Nachrichtenflusses.
  • Ihr Empfangsknoten enthält immer mindestens einen Thread, entweder einen, der Daten aus der Eingabequelle liest, oder einen, der eine empfangene Nachricht aktiv verarbeitet. Wenn ein Nachrichtenfluss mehrere Empfangsknoten enthält, stehen zusätzliche Threadinstanzen zur Verfügung, um die einzelnen Empfangsknoten zu bedienen, so wie von der Zuteilungsrichtlinie des jeweiligen Empfangsknotens festgelegt.
Threads können abgerufen bzw. angefordert werden. Nach dem Einsetzen eines Nachrichtenflusses fordert der Empfangsknoten einen Anfangsthread an. Obwohl der Nachrichtenfluss über einen Pool von ihm zugeordneten Threads verfügt, ist es der Empfangsknoten, der für die Zuteilung zuständig ist. Das heißt, er muss sicherstellen, dass immer eine Instanz von ihm selbst in einem Thread aktiv ist. Da der Standardwert für die Eigenschaft additionalInstances null ist, schlagen alle weiteren Anforderungen von Threads fehl, wenn Sie mehrere Empfangsknoten definiert haben. Deshalb kann es sein, dass ein Nachrichtenfluss mehr Threads beansprucht als erwartet. Falls Sie mehrere Empfangsknoten definiert haben, kann dies auch bedeuten, dass für einen der Empfangsknoten möglicherweise keine Threads verfügbar sind.

Die effizienteste Methode, um zu verhindern, dass die Eingabewarteschlange zu einem Engpass wird, besteht darin, dem Broker über die Eigenschaft additionalInstances zu erlauben, zusätzliche Kopien des Nachrichtenflusses in separaten Threads zu starten. Bei separaten Threads ist es jedoch möglich, dass eine Parallelverarbeitung von Nachrichten aus der Nachrichtenwarteschlange stattfindet. Daher sollten Sie diese Methode nur verwenden, wenn die Reihenfolge, in der die Nachrichten verarbeitet werden, nicht wichtig ist.

Threads werden als Ergebnis der Erstellung und des Betriebs eines Empfangsknotens erstellt. Ein Thread steht immer als aktiver oder inaktiver Thread im Thread-Pool. Inaktive Threads bleiben so lange im Pool stehen, bis sie von einem Empfangsknoten zugeteilt werden oder der Broker heruntergefahren wird.

Die folgende Abbildung zeigt die Threadzuordnung in einem Nachrichtenfluss.

Threadzuordnung in einem Nachrichtenfluss

Im Begleittext finden Sie eine Erläuterung der Elemente im Diagramm

Als erstes wird Thread 1 angefordert (A) und wartet auf Nachrichten. Sobald eine Nachricht ankommt (B), gibt Thread 1 sie weiter und teilt Thread 2 zu. Thread 2 empfängt sofort eine Nachricht (C), gibt sie weiter und teilt Thread 3 zu, der auf eine Nachricht wartet (D). Thread 1 beendet die Verarbeitung (E) und wird zurück in den Thread-Pool gestellt. Dann empfängt Thread 3 eine Nachricht (F), teilt Thread 1 zu und gibt die Nachricht weiter. Thread 1 wartet jetzt darauf, dass eine Nachricht in der Warteschlange ankommt (G).

Es lohnt sich ein genauer Blick auf den Punkt H. An dieser Stelle im Nachrichtenfluss erhält Thread 1 eine Nachricht, kann aber keine Zuteilung vornehmen, weil alle anderen Threads gerade aktiv sind. Die Nachricht wird weitergegeben.

Nachdem diese Nachricht weitergegeben wurde, beendet Thread 2 die Verarbeitung (I), empfängt eine neue Nachricht aus der Warteschlange und gibt diese neue Nachricht weiter. Dann beendet Thread 3 die Verarbeitung (J) und wird zurück in den Pool gestellt. Anschließend beendet auch Thread 2 die Verarbeitung (K). Da Thread 1 nach Abschluss der Verarbeitung keine Zuteilung vornehmen konnte (L), kann er nicht zurück in den Thread-Pool gestellt werden, obwohl keine Nachrichten in der Warteschlange enthalten sind, sondern wartet stattdessen darauf, dass eine Nachricht in der Warteschlange ankommt.

Beachten Sie die folgenden Hinweise zum Verhalten von Threads in WebSphere Message Broker:
  • Threads werden nur erstellt, wenn die Auslastung dies erfordert. Das heißt, dass ein Ausführungsgruppenprozess möglicherweise mit weniger Threads auskommt, als für ihn konfiguriert wurden.
  • Falls nicht alle verfügbaren Threads in einem Nachrichtenfluss gerade eine Verarbeitung durchführen, ist immer ein Thread vorhanden, der die Eingabewarteschlange liest.
  • Wenn die Auslastung zu einem beliebigen Zeitpunkt zunimmt, können andere Empfangsknoten im selben Nachrichtenfluss Threads, die in den Thread-Pool zurückgestellt wurden, in Anspruch nehmen.
Wenn ein Thread eine Nachricht entgegennimmt, aber alle anderen Threads gerade aktiv sind, kann er keine Zuteilung vornehmen. Die Nachricht wird weitergegeben. Wenn dieser Thread die Verarbeitung beendet, aber keine Zuteilung vornehmen konnte, kann er nicht zurück in den Thread-Pool gestellt werden, auch wenn keine Nachrichten in der Warteschlange enthalten sind.
Zugehörige Konzepte
Benutzerdefinierte Empfangsknoten
Zugehörige Verweise
cniDispatchThread
Bemerkungen | Marken | Downloads | Bibliothek | Unterstützung | Rückmeldung
Copyright IBM Corporation 1999, 2006 Letzte Aktualisierung: 23. Aug. 2006
as01460_