Muster des Leistungsschalters - AWS Präskriptive Leitlinien

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Muster des Leistungsschalters

Absicht

Das Circuit Breaker-Muster kann verhindern, dass ein Anruferdienst erneut versucht, einen anderen Dienst (Anrufer) anzurufen, obwohl der Anruf zuvor zu wiederholten Timeouts oder Ausfällen geführt hat. Das Muster wird auch verwendet, um zu erkennen, wann der angerufene Dienst wieder funktionsfähig ist.

Motivation

Wenn mehrere Microservices zusammenarbeiten, um Anfragen zu bearbeiten, kann es sein, dass ein oder mehrere Dienste nicht verfügbar sind oder eine hohe Latenz aufweisen. Wenn komplexe Anwendungen Microservices verwenden, kann ein Ausfall eines Microservices zum Ausfall der Anwendung führen. Microservices kommunizieren über Remote-Prozeduraufrufe, und es können vorübergehende Fehler bei der Netzwerkkonnektivität auftreten, die zu Ausfällen führen. (Die vorübergehenden Fehler können mithilfe des Musters „Wiederholungsversuch mit Backoff“ behandelt werden.) Während der synchronen Ausführung kann die Kaskadierung von Timeouts oder Ausfällen zu einer schlechten Benutzererfahrung führen.

In einigen Situationen kann es jedoch länger dauern, bis die Fehler behoben sind, z. B. wenn der aufgerufene Dienst ausgefallen ist oder ein Datenbankkonflikt zu Timeouts führt. In solchen Fällen, wenn der aufrufende Dienst die Aufrufe wiederholt wiederholt, können diese Wiederholungen zu Netzwerkkonflikten und zur Auslastung des Datenbank-Threadpools führen. Wenn mehrere Benutzer die Anwendung wiederholt wiederholen, verschlimmert sich das Problem zusätzlich und kann zu Leistungseinbußen in der gesamten Anwendung führen.

Das Circuit Breaker Pattern wurde von Michael Nygard in seinem Buch Release It (Nygard 2018) populär gemacht. Dieses Entwurfsmuster kann verhindern, dass ein Anruferdienst einen Serviceanruf wiederholt, der zuvor zu wiederholten Timeouts oder Ausfällen geführt hat. Es kann auch erkennen, wann der angerufene Dienst wieder funktionsfähig ist.

Schutzschalterobjekte funktionieren wie elektrische Schutzschalter, die den Strom automatisch unterbrechen, wenn im Stromkreis eine Störung auftritt. Elektrische Schutzschalter schalten den Stromfluss ab oder lösen ihn aus, wenn eine Störung vorliegt. In ähnlicher Weise befindet sich das Schutzschalter-Objekt zwischen dem Anrufer und dem angerufenen Dienst und löst aus, wenn der Anrufer nicht verfügbar ist.

Die Irrtümer des verteilten Rechnens sind eine Reihe von Behauptungen, die von Peter Deutsch und anderen Mitarbeitern von Sun Microsystems aufgestellt wurden. Sie sagen, dass Programmierer, die mit verteilten Anwendungen noch nicht vertraut sind, ausnahmslos falsche Annahmen treffen. Die Netzwerkzuverlässigkeit, die Erwartung, keine Latenz zu haben und Bandbreitenbeschränkungen führen dazu, dass Softwareanwendungen mit minimaler Fehlerbehandlung für Netzwerkfehler geschrieben werden.

Während eines Netzwerkausfalls warten Anwendungen möglicherweise auf unbestimmte Zeit auf eine Antwort und verbrauchen kontinuierlich Anwendungsressourcen. Wenn die Vorgänge nicht wiederholt werden, wenn das Netzwerk wieder verfügbar ist, kann dies ebenfalls zu einer Verschlechterung der Anwendung führen. Wenn bei API Aufrufen einer Datenbank oder eines externen Dienstes aufgrund von Netzwerkproblemen ein Timeout auftritt, können wiederholte Anrufe ohne Schutzschalter Kosten und Leistung beeinträchtigen.

Anwendbarkeit

Verwenden Sie dieses Muster, wenn:

  • Der Anruferdienst tätigt einen Anruf, der höchstwahrscheinlich fehlschlagen wird.

  • Eine hohe Latenz, die der angerufene Dienst aufweist (z. B. wenn die Datenbankverbindungen langsam sind), führt zu Timeouts beim angerufenen Dienst.

  • Der Anruferdienst tätigt einen synchronen Anruf, aber der angerufene Dienst ist nicht verfügbar oder weist eine hohe Latenz auf.

Fehler und Überlegungen

  • Dienstunabhängige Implementierung: Um zu verhindern, dass der Code aufgebläht wird, empfehlen wir, das Circuit-Breaker-Objekt auf Microservice-unabhängige und -gesteuerte Weise zu implementieren. API

  • Schließung des Stromkreises durch den Angerufenen: Wenn der Angerufene das Leistungsproblem oder den Ausfall behoben hat, kann er den Verbindungsstatus auf ändern. CLOSED Dies ist eine Erweiterung des Schutzschaltermusters und kann implementiert werden, wenn Ihr Wiederherstellungszeitziel (RTO) dies erfordert.

  • Multithread-Anrufe: Der Wert für das Ablauf-Timeout ist definiert als der Zeitraum, für den die Verbindung ausgelöst bleibt, bevor Anrufe erneut weitergeleitet werden, um die Verfügbarkeit des Dienstes zu überprüfen. Wenn der angerufene Dienst in mehreren Threads aufgerufen wird, definiert der erste fehlgeschlagene Anruf den Wert für das Ablauftimeout. Ihre Implementierung sollte sicherstellen, dass bei nachfolgenden Aufrufen das Ablauftimeout nicht endlos verschoben wird.

  • Erzwungenes Öffnen oder Schließen des Stromkreises: Systemadministratoren sollten in der Lage sein, einen Kreislauf zu öffnen oder zu schließen. Dies kann erreicht werden, indem der Wert für das Ablauftimeout in der Datenbanktabelle aktualisiert wird.

  • Beobachtbarkeit: In der Anwendung sollte eine Protokollierung eingerichtet sein, um die Anrufe zu identifizieren, die fehlschlagen, wenn der Schutzschalter geöffnet ist.

Implementierung

Hochrangige Architektur

Im folgenden Beispiel ist der Anrufer der Bestelldienst und der Angerufene der Zahlungsdienst.

Liegen keine Ausfälle vor, leitet der Bestellservice alle Anrufe über den Schutzschalter an den Zahlungsdienst weiter, wie das folgende Diagramm zeigt.

Leistungsschalter-Muster ohne Ausfälle.

Wenn beim Zahlungsdienst ein Timeout auftritt, kann der Schutzschalter den Timeout erkennen und den Ausfall nachverfolgen.

Schutzschalter bei Ausfall des Zahlungsdienstes.

Wenn die Timeouts einen bestimmten Schwellenwert überschreiten, öffnet die Anwendung den Stromkreis. Wenn der Stromkreis geöffnet ist, leitet das Circuit Breaker-Objekt die Anrufe nicht an den Zahlungsdienst weiter. Wenn der Bestellservice den Zahlungsdienst aufruft, wird sofort ein Fehler gemeldet.

Der Leistungsschalter stoppt die Weiterleitung zum Zahlungsdienst.

Das Circuit Breaker-Objekt versucht in regelmäßigen Abständen festzustellen, ob die Aufrufe an den Zahlungsdienst erfolgreich waren.

Circuit Breaker versucht in regelmäßigen Abständen erneut, den Zahlungsdienst zu bezahlen.

Wenn der Anruf beim Zahlungsdienst erfolgreich ist, wird die Verbindung geschlossen und alle weiteren Anrufe werden wieder an den Zahlungsdienst weitergeleitet.

Schutzschalter mit funktionierendem Zahlungsdienst.

Implementierung mithilfe von AWS Diensten

Die Beispiellösung verwendet Express-Workflows AWS Step Functions, um das Circuit Breaker Pattern zu implementieren. Mit der Step Functions Functions-Zustandsmaschine können Sie die Wiederholungsfunktionen und den entscheidungsbasierten Kontrollfluss konfigurieren, die für die Musterimplementierung erforderlich sind.

Die Lösung verwendet auch eine Amazon DynamoDB-Tabelle als Datenspeicher, um den Schaltkreisstatus zu verfolgen. Dieser kann für eine bessere Leistung durch einen In-Memory-Datenspeicher wie Amazon ElastiCache (RedisOSS) ersetzt werden.

Wenn ein Dienst einen anderen Dienst aufrufen möchte, startet er den Workflow mit dem Namen des aufgerufenen Dienstes. Der Workflow ruft den Circuit Breaker-Status aus der CircuitStatus DynamoDB-Tabelle ab, in der die aktuell heruntergestuften Dienste gespeichert sind. CircuitStatusEnthält er einen noch nicht abgelaufenen Datensatz für den Angerufenen, ist der Circuit geöffnet. Der Step Functions Functions-Workflow gibt einen sofortigen Fehler zurück und wird mit einem FAIL Status beendet.

Wenn die CircuitStatus Tabelle keinen Datensatz für den Angerufenen oder einen abgelaufenen Datensatz enthält, ist der Dienst betriebsbereit. Der ExecuteLambda Schritt in der State-Machine-Definition ruft die Lambda-Funktion auf, die über einen Parameterwert gesendet wird. Wenn der Aufruf erfolgreich ist, wird der Step Functions Functions-Workflow mit einem SUCCESS Status beendet.

Implementierung von Leistungsschaltern mit AWS Step Functions und DynamoDB.

Schlägt der Serviceaufruf fehl oder tritt ein Timeout auf, versucht die Anwendung es mit exponentiellem Backoff für eine bestimmte Anzahl von Malen erneut. Schlägt der Serviceaufruf nach den Wiederholungen fehl, fügt der Workflow einen Datensatz mit dem Zeichen an in die CircuitStatus Tabelle für den Dienst einExpiryTimeStamp, und der Workflow wird mit einem Status beendet. FAIL Bei nachfolgenden Aufrufen desselben Dienstes wird sofort ein Fehler gemeldet, sofern der Schutzschalter geöffnet ist. Der Get Circuit Status Schritt in der State-Machine-Definition überprüft die Verfügbarkeit des Dienstes anhand des ExpiryTimeStamp Werts. Abgelaufene Elemente werden mithilfe der DynamoDB-Funktion time to live (TTL) aus der CircuitStatus Tabelle gelöscht.

Beispiel-Code

Der folgende Code verwendet die GetCircuitStatus Lambda-Funktion, um den Status des Leistungsschalters zu überprüfen.

var serviceDetails = _dbContext.QueryAsync<CircuitBreaker>(serviceName, QueryOperator.GreaterThan, new List<object> {currentTimeStamp}).GetRemainingAsync(); if (serviceDetails.Result.Count > 0) { functionData.CircuitStatus = serviceDetails.Result[0].CircuitStatus; } else { functionData.CircuitStatus = ""; }

Der folgende Code zeigt die Amazon States-Sprachanweisungen im Step Functions Functions-Workflow.

"Is Circuit Closed": { "Type": "Choice", "Choices": [ { "Variable": "$.CircuitStatus", "StringEquals": "OPEN", "Next": "Circuit Open" }, { "Variable": "$.CircuitStatus", "StringEquals": "", "Next": "Execute Lambda" } ] }, "Circuit Open": { "Type": "Fail" }

GitHub Repository

Eine vollständige Implementierung der Beispielarchitektur für dieses Muster finden Sie im GitHub Repository unter https://github.com/aws-samples/circuit-breaker-netcore-blog.

Blog-Referenzen

Verwandter Inhalt