Muster für einen sequenziellen Konvoi

Functions
Service Bus

Verarbeiten Sie eine Reihe verwandter Nachrichten in einer festgelegten Reihenfolge, ohne die Verarbeitung anderer Nachrichtengruppen zu blockieren.

Kontext und Problem

Anwendungen müssen häufig eine Reihe von Nachrichten in der Reihenfolge verarbeiten, in der sie empfangen werden, und gleichzeitig horizontal hochskalieren, um die erhöhte Auslastung zu verarbeiten. In einer verteilten Architektur ist die Verarbeitung dieser Nachrichten in der richtigen Reihenfolge nicht ganz einfach, da die Worker unabhängig voneinander skalieren können und die Nachrichten oft unabhängig mithilfe von Pull übertragen werden, indem sie das Muster „Konkurrierende Consumer“ verwenden.

Ein System zur Auftragsnachverfolgung erhält z. B. einen Ledger, der Aufträge und die relevanten Vorgänge für diese Aufträge enthält. Mit diesen Vorgängen kann ein Auftrag erstellt, dem Auftrag eine Transaktion hinzugefügt, eine vergangene Transaktion geändert oder ein Auftrag gelöscht werden. In diesem System müssen Vorgänge nach dem FIFO-Prinzip (First In, First Out) ausgeführt werden, allerdings nur auf Auftragsebene. Die anfängliche Warteschlange erhält jedoch einen Ledger, der Transaktionen für viele Aufträge enthält, die möglicherweise verschachtelt sind.

Lösung

Übertragen Sie verwandte Nachrichten in Kategorien innerhalb des Warteschlangensystems mithilfe von Push, und lassen Sie die Warteschlangenlistener nur für eine Kategorie für jeweils eine Nachricht Sperr- und Pullvorgänge ausführen.

Das allgemeine Muster für den sequenziellen Konvoi sieht wie folgt aus:

Diagram of Sequential Convoy pattern

In der Warteschlange können Nachrichten für verschiedene Kategorien verschachtelt sein, wie im folgenden Diagramm dargestellt:

Diagram showing interleaved messages

Probleme und Überlegungen

Beachten Sie die folgenden Punkte bei der Entscheidung, wie dieses Muster implementiert werden soll:

  • Kategorie/Skalierungseinheit: Für welche Eigenschaft der eingehenden Nachrichten können Sie horizontal hochskalieren? Im Szenario zur Auftragsnachverfolgung ist diese Eigenschaft die Auftrags-ID.
  • Durchsatz. Wie ist der Durchsatz Ihrer Zielnachricht? Wenn er sehr hoch ist, müssen Sie möglicherweise Ihre FIFO-Anforderungen überdenken. Können Sie z. B. eine Start- oder Endnachricht erzwingen, nach der Zeit sortieren und dann einen Batch für die Verarbeitung senden?
  • Gerätefunktionen: Ermöglicht die Auswahl des Nachrichtenbus die einmalige Verarbeitung von Nachrichten in einer Warteschlange oder einer Kategorie einer Warteschlange?
  • Evolvierbarkeit: Wie wird dem System eine neue Nachrichtenkategorie hinzugefügt? Nehmen wir beispielsweise an, dass das oben beschriebene Ledgersystem spezifisch für einen Kunden ist. Wenn Sie für einen neuen Kunden ein Onboarding durchführen müssen, können Sie über mehrere Ledgerprozessoren verfügen, die Arbeit pro Kunden-ID verteilen?
  • Es ist möglich, dass Consumer aufgrund variabler Netzwerklatenz beim Senden von Nachrichten eine Nachricht möglicherweise nicht in der richtigen Reihenfolge erhalten. Verwenden Sie zum Überprüfen der Reihenfolge die Sequenznummern. Sie können auch ein spezielles Flag „Ende der Sequenz“ in die letzte Nachricht der Transaktion einschließen. Technologien zur Streamverarbeitung wie Spark oder Azure Stream Analytics können Nachrichten innerhalb eines Zeitfensters in der richtigen Reihenfolge verarbeiten.

Verwendung dieses Musters

Verwenden Sie dieses Muster in folgenden Fällen:

  • Sie haben Nachrichten, die in der richtigen Reihenfolge eintreffen und in derselben Reihenfolge verarbeitet werden müssen.
  • Eingehende Nachrichten können so „kategorisiert“ werden, dass die Kategorie zu einer Skalierungseinheit für das System wird.

Dieses Muster ist in folgendem Fall möglicherweise nicht geeignet:

  • Extrem hohe Durchsatzszenarios (Millionen von Nachrichten pro Minute oder Sekunde), da die FIFO-Anforderung die Skalierung einschränkt, die vom System durchgeführt werden kann.

Beispiel

In Azure kann dieses Muster mithilfe von Nachrichtensitzungen von Azure Service Bus implementiert werden. Für die Consumer können Sie entweder Logik-Apps mit dem Service Bus-Peek-Lock-Connector oder Azure Functions mit dem Service Bus-Trigger verwenden.

Verarbeiten Sie im vorherigen Beispiel zur Auftragsnachverfolgung jede Ledgernachricht in der Reihenfolge, in der sie empfangen wird, und senden Sie jede Transaktion an eine andere Warteschlange, in der die Kategorie auf die Auftrags-ID festgelegt ist. Eine Transaktion umfasst in diesem Szenario nie mehrere Aufträge, sodass die Kunden jede Kategorie parallel, aber FIFO innerhalb der Kategorie verarbeiten.

Der Ledgeprozessor gibt alle Nachrichten aus, indem der Inhalt der einzelnen Nachrichten in der ersten Warteschlange aufgeschlüsselt wird:

Diagram showing Sequential Convoy pattern with a ledger queue

Der Ledgerprozessor kümmert sich um Folgendes:

  1. Der Ledger durchläuft eine Transaktion nach der anderen.
  2. Die Sitzungs-ID der Nachricht wird entsprechend der Auftrags-ID festgelegt.
  3. Jede Ledgertransaktion wird an eine sekundäre Warteschlange gesendet, wobei die Sitzungs-ID auf die Auftrags-ID festgelegt ist.

Die Consumer lauschen an der sekundären Warteschlange, in der alle Nachrichten mit übereinstimmenden Auftrags-IDs in Reihenfolge aus der Warteschlange verarbeitet werden. Die Consumer verwenden den Peek-Lock-Modus.

Wenn Sie die Skalierbarkeit berücksichtigen, stellt die Ledgerwarteschlange einen primären Engpass dar. Verschiedene Transaktionen, die für den Ledger bereitgestellt werden, können auf die gleiche Auftrags-ID verweisen. Nachrichten können jedoch nach dem Ledger an die Anzahl der Aufträge in einer serverlosen Umgebung gesendet werden.

Nächste Schritte

Die folgenden Informationen sind unter Umständen auch relevant, wenn dieses Muster implementiert wird: