Warteschlangenbasiertes Lastenausgleichsmuster

Azure-Funktionen
Azure-Servicebus

Verwenden Sie eine Warteschlange, die als Puffer zwischen einem Task und einem von ihm aufgerufenen Dienst fungiert, um unregelmäßig auftretende hohe Lasten aufzufangen, die den Ausfall des Diensts oder eine Zeitüberschreitung des Tasks verursachen können. Dies kann dazu beitragen, die Auswirkungen von Bedarfsspitzen auf die Verfügbarkeit und Reaktionsfähigkeit von Task und Dienst zu minimieren.

Kontext und Problem

Viele Lösungen in der Cloud beinhalten das Ausführen von Tasks, die Dienste aufrufen. Wenn in dieser Umgebung ein Dienst zeitweilig starken Lasten ausgesetzt ist, kann dies Probleme bei der Leistung oder Zuverlässigkeit verursachen.

Ein Dienst kann in derselben Lösung enthalten sein wie die Tasks, die ihn verwenden, oder es kann sich um einen Drittanbieterdienst handeln, der Zugriff auf häufig genutzte Ressourcen bietet, z.B. ein Cache oder Speicherdienst. Wenn derselbe Dienst von mehreren gleichzeitig ausgeführten Tasks verwendet wird, ist die Menge der zu einem bestimmten Zeitpunkt an den Dienst gesendeten Anforderungen eventuell schwierig vorherzusagen.

Bei einem Dienst können Bedarfsspitzen auftreten, die dazu führen, dass der Dienst überlastet ist und nicht zeitgerecht auf Anforderungen reagieren kann. Die Belastung eines Diensts durch eine große Anzahl gleichzeitiger Anforderungen kann auch zum Ausfall des Diensts führen, wenn er die durch diese Anforderungen verursachten Konflikte nicht bewältigen kann.

Lösung

Gestalten Sie die Lösung um, und setzen Sie zwischen den Task und den Dienst eine Warteschlange. Der Task und der Dienst werden asynchron ausgeführt. Der Task sendet eine Nachricht mit den für den Dienst erforderlichen Daten an die Warteschlange. Die Warteschlange fungiert als Puffer, der die Nachricht speichert, bis sie vom Dienst abgerufen wird. Der Dienst empfängt die Nachrichten aus der Warteschlange und verarbeitet sie. Anforderungen von mehreren Tasks, die mit einer stark schwankenden Rate generiert werden können, können über dieselbe Nachrichtenwarteschlange an den Dienst übergeben werden. In dieser Abbildung wird die Verwendung einer Warteschlange zum Ausgleichen der Last für einen Dienst gezeigt.

Abbildung 1 – Verwenden einer Warteschlange zum Ausgleichen der Last für einen Dienst

Die Warteschlange entkoppelt die Tasks vom Dienst, und der Dienst kann die Nachrichten mit der ihm angemessenen Geschwindigkeit behandeln, unabhängig von der Menge der Anforderungen von gleichzeitigen Tasks. Zudem wird ein Task nicht verzögert, wenn der Dienst zu dem Zeitpunkt, zu dem der Task eine Nachricht an die Warteschlange sendet, nicht verfügbar ist.

Dieses Muster bietet folgende Vorteile:

  • Es kann zum Erhöhen der Verfügbarkeit beitragen, da Verzögerungen in Diensten keine unverzügliche und direkte Auswirkung auf die Anwendung haben. Diese kann weiter Nachrichten an die Warteschlange senden, selbst wenn der Dienst nicht verfügbar ist oder Nachrichten nicht parallel verarbeitet.

  • Es kann zum Erhöhen der Skalierbarkeit beitragen, da sowohl die Anzahl der Warteschlangen als auch die Anzahl der Dienste an den Bedarf angepasst werden können.

  • Es kann zur Kontrolle der Kosten beitragen, da die Anzahl der bereitgestellten Dienstinstanzen nur der durchschnittlichen Last und nicht der Spitzenlast entsprechen muss.

    Manche Dienste implementieren Drosselung, wenn der Bedarf einen Schwellenwert erreicht, nach dessen Überschreiten das System ausfallen kann. Durch die Drosselung kann die verfügbare Funktionalität reduziert werden. Sie können für diese Dienste Lastenausgleich implementieren, um zu verhindern, dass dieser Schwellenwert erreicht wird.

Probleme und Überlegungen

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

  • Es muss Anwendungslogik implementiert werden, mit der die Rate der Verarbeitung von Nachrichten durch Dienste gesteuert wird, um eine Überlastung der Zielressource zu verhindern. Reichen Sie Bedarfsspitzen nicht an die nächste Stufe im System weiter. Testen Sie das System unter Last, um sicherzustellen, dass es den erforderlichen Ausgleich bietet, und passen Sie die Anzahl der Warteschlangen und die Anzahl der Dienstinstanzen, die Nachrichten verarbeiten, entsprechend an.
  • Nachrichtenwarteschlangen sind ein unidirektionaler Kommunikationsmechanismus. Wenn ein Task eine Antwort von einem Dienst erwartet, muss möglicherweise ein Mechanismus implementiert werden, den der Dienst zum Senden einer Antwort verwenden kann. Weitere Informationen finden Sie unter Einführung in asynchrone Nachrichten.
  • Gehen Sie vorsichtig vor, wenn Sie die automatische Skalierung auf Dienste anwenden, die auf Anforderungen in der Warteschlange lauschen. Dies kann die Konflikte um Ressourcen erhöhen, die von diesen Diensten gemeinsam genutzt werden, und die Effektivität der Verwendung der Warteschlange für den Lastenausgleich verringern.
  • Je nach Auslastung des Diensts kann es geschehen, dass Sie praktisch immer hinterherhinken, während das System immer mehr Anforderungen in die Warteschlange stellt, als Sie verarbeiten können. Die Schwankungen beim eingehenden Datenverkehr für Ihre Anwendung müssen berücksichtigt werden.
  • Beim Muster können je nach Persistenz der Warteschlange Informationen verloren gehen. Wenn Ihre Warteschlange abstürzt oder Informationen verloren gehen (aufgrund von Systemgrenzwerten), besteht die Möglichkeit einer nicht garantierten Übermittlung. Das Verhalten Ihrer Warteschlangen und Systemgrenzwerte müssen entsprechend den Anforderungen Ihrer Lösung berücksichtigt werden.

Verwendung dieses Musters

Dieses Muster ist für jede Anwendung hilfreich, die Dienste verwendet, die Überlastung ausgesetzt sind.

Dieses Muster ist nicht hilfreich, wenn die Anwendung eine Antwort vom Dienst mit minimaler Wartezeit erwartet.

Workloadentwurf

Ein Architekt sollte evaluieren, wie das Queue-Based Load Leveling-Pattern im Design seiner Workloads eingesetzt werden kann, um die Ziele und Prinzipien zu erreichen, die in den Säulen des Azure Well-Architected Framework behandelt werden. Zum Beispiel:

Säule So unterstützt dieses Muster die Säulenziele
Zuverlässigkeitsdesignentscheidungen tragen dazu bei, dass Ihre Workload ausfallsicher wird und dass sie nach einem Ausfall wieder in einen voll funktionsfähigen Zustand zurückkehrt. Der in diesem Muster beschriebene Ansatz kann plötzliche Nachfragespitzen abfedern, indem er das Eintreffen von Aufgaben von deren Bearbeitung entkoppelt. Es kann auch Störungen bei der Verarbeitung von Warteschlangen isolieren, so dass sie sich nicht auf die Aufnahme auswirken.

- RE:06 Skalierung
- RE:07 Hintergrundaufträge
Die Kostenoptimierung konzentriert sich auf Erhaltung und Verbesserung der Rendite Ihrer Workload. Da die Lastverarbeitung von der Aufnahme von Anfragen oder Aufgaben entkoppelt ist, können Sie diesen Ansatz nutzen, um die Notwendigkeit einer Überversorgung mit Ressourcen zur Bewältigung von Lastspitzen zu verringern.

- CO:12 Skalierungskosten
Die Leistungseffizienz hilft Ihrer Workload, Anforderungen effizient durch Optimierungen in Skalierung, Daten und Code zu erfüllen. Dieser Ansatz ermöglicht eine gezielte Planung der Durchsatzleistung, da der Eingang von Anfragen nicht mit der Geschwindigkeit ihrer Verarbeitung korrelieren muss.

- PE:05 Skalierung und Partitionierung

Berücksichtigen Sie wie bei jeder Designentscheidung alle Kompromisse im Hinblick auf die Ziele der anderen Säulen, die mit diesem Muster eingeführt werden könnten.

Beispiel

Eine Web-App schreibt Daten in einen externen Datenspeicher. Bei gleichzeitiger Ausführung zahlreicher Instanzen der Web-App kann der Datenspeicher möglicherweise nicht schnell genug auf Anforderungen reagieren, was zu Anforderungstimeouts, zur Drosselung von Anforderungen oder zu anderen Fehlern führen kann. Das folgende Diagramm zeigt einen Datenspeicher, der aufgrund einer großen Menge gleichzeitiger Anforderungen von Instanzen einer Anwendung überlastet ist:

Abbildung 2: Ein Dienst, der aufgrund einer großen Menge gleichzeitiger Anforderungen von Instanzen einer Web-App überlastet ist.

Zur Behebung dieses Problems können Sie eine Warteschlange für den Lastenausgleich zwischen den Anwendungsinstanzen und dem Datenspeicher verwenden. Eine Azure Functions-App liest die Nachrichten aus der Warteschlange und führt die an den Datenspeicher gerichteten Lese-/Schreibanforderungen aus. Die Anwendungslogik in der Funktions-App kann die Rate steuern, mit der Anforderungen an den Datenspeicher übergeben werden, um eine Überlastung des Datenspeichers zu verhindern. (Andernfalls verursacht die Funktions-App das gleiche Problem am Back-End.)

Abbildung 3: Verwenden einer Warteschlange und einer Funktions-App für den Lastenausgleich

Nächste Schritte

Die folgenden Richtlinien sind unter Umständen beim Implementieren dieses Musters ebenfalls relevant:

  • Architekturstil „Web-Warteschlange-Worker“. Web und Worker sind jeweils zustandslos. Der Sitzungsstatus kann in einem verteilten Cache zwischengespeichert werden. Alle Vorgänge mit langer Ausführungsdauer werden asynchron vom Worker durchgeführt. Der Worker kann über Nachrichten in der Warteschlange ausgelöst oder nach einem Zeitplan für die Batchverarbeitung ausgeführt werden.

Die folgenden Muster sind unter Umständen bei der Implementierung dieses Musters ebenfalls relevant:

  • Muster „Konkurrierende Consumer“: Möglicherweise können mehrere Instanzen eines Diensts ausgeführt werden, von denen jede als Consumer von Nachrichten aus der Warteschlange für den Lastenausgleich fungiert. Sie können diesen Ansatz verwenden, um die Rate anzupassen, mit der Nachrichten empfangen und an einen Dienst übergeben werden.

  • Muster „Drosselung“: Eine einfache Möglichkeit zum Implementieren von Drosselung für einen Dienst ist die Verwendung von warteschlangenbasiertem Lastenausgleich und die Weiterleitung aller Anforderungen an einen Dienst über eine Nachrichtenwarteschlange. Der Dienst kann Anforderungen mit einer Rate verarbeiten, die sicherstellt, dass die für den Dienst erforderlichen Ressourcen nicht erschöpft werden, und mit der die möglicherweise auftretenden Konflikte reduziert werden.