Je nachdem, wie viele Anfragen nacheinander an den Webservice gesandt werden, kann dies die Abarbeitung einer Orchestration erheblich verzögern. In unserem Fall war diese Verzögerung so groß, dass es zu weiteren Problemen im Kundensystem führte. Doch erst einmal zu einer vereinfachten Version der Ausgangssituation:
Abb. 1 Übersicht über die ursprüngliche Orchestration
Unsere zu optimierende Orchestration hat eine Liste von Abfragen, die an den Webservice gestellt werden sollen und deren Ergebnis weiter verarbeitet wird (z.B. zur Fehlerbehandlung). Diese Liste wird in einer Schleife abgearbeitet. Wenn nun pro Interaktion mit dem Webservice 5-10 Sekunden benötigt werden, ist leicht abzuschätzen, wie sich das auf die gesamte Laufzeit auswirkt. Wir hatten bis zu 1000 Anfragen je Aufruf der Orchestration zu bearbeiten. Da die einzelnen Anfragen jedoch nicht aufeinander aufbauten, konnte Parallelisierung eine mögliche Lösung sein.
Nun gibt es einige Ansätze bei BizTalk, die Arbeit an andere Orchestrations auszulagern. Es stehen zwei Shapes zur Verfügung: „Call Orchestration“ und „Start Orchestration“. Da nur "Start Orchestration" in einem neuen, unabhängigen Thread gestartet wird, war dies die einzige Wahl (Stichwort Multiprocessing). Der Gedanke bei der Modellierung war, den Prozess aufzuteilen: Eine Phase, in der alle Anfragen gestartet werden und eine, in der die Antworten gesammelt werden. Dieses Messaging Prinzip nennt man „Scatter & Gather“.
Die noch offene Frage dabei: Wie läuft die Kommunikation zwischen gestarteter und startender Orchestration ab? Denn – für die Fehlerbehandlung wollten wir einen Status von der Abfrage erhalten. Für den Start-Shape ist jedoch kein Rückgabewert vorgesehen. Dafür kann allerdings die interne Messagebox von BizTalk genutzt werden.
In der Portkonfiguration wird es etwas verwirrend, denn wir benötigen keinen Port zur Kommunikation mit anderen Orchestrations, sondern einen self-correlating Port (s. Abb. 2) – sonst müsste die Korrelation händisch bewerkstelligt werden.
Abb. 2 Anlage eines self correlating Ports:
Um die Korrelation herzustellen, muss der empfangende Teil in der startenden Orchestration zuerst angelegt werden und der gestarteten Orchestration als „Configured Port Parameter“ übergeben werden (s. Abb. 3 und 4).
Abb. 3: Hinzufügen eines Ports als Orchestration Parameter
Abb. 4: Auswahl des Ports im "Start Orchestration" Shape
Abb. 5: Übersicht über die neue Kind-Orchestration
War es am Ende eine deutliche Verbesserung?
Wir konnten in vereinfachten Tests eine drastische Verminderung der Laufzeit feststellen. So dauerte der Vorgang auf unserem Testsystem bei konstanten 3 Sekunden pro Abfrage:
Für 100 Abfragen:
- sequentiell 6min 6s
- parallel 35s.
Für 1000 Abfragen:
- sequentiell 1h 4min
- parallel 4min 38s.
Damit ein voller Erfolg für unsere Parallelisierung!
Wilhelm Tschakert, QUIBIQ Berlin