AWS Germany – Amazon Web Services in Deutschland
Verwendung des Circuit Breaker Pattern mit AWS Lambda-Erweiterungen und Amazon DynamoDB
Moderne Softwaresysteme sind häufig auf Remote-Aufrufe zu anderen Systemen über Netzwerke angewiesen. Wenn Ausfälle auftreten, können sie sich über mehrere Dienste hinweg ausbreiten und zu Dienstunterbrechungen führen. Eine Technik zur Minderung dieses Risikos ist das Circuit Breaker Pattern, mit dem Ausfälle in einem verteilten System erkannt und isoliert werden können. Das Circuit Breaker Pattern kann dazu beitragen, kaskadierende Ausfälle zu verhindern und die allgemeine Systemstabilität zu verbessern.
Darüber hinaus erhöht es auch die Fehlertoleranz des Systems, da es dem System ermöglicht, mit dem betroffenen Dienst wieder zu interagieren, sobald dieser verfügbar ist.
In diesem Blogpost wird eine Beispielanwendung vorgestellt, die zeigt, wie AWS Lambda-Erweiterungen mit Amazon DynamoDB genutzt werden, um das Circuit Breaker Pattern zu implementieren.
Verwendung von Lambda-Erweiterungen zur Implementierung des Circuit Breaker Pattern
AWS Lambda ist ein Rechendienst, mit dem Sie Anwendungen erstellen können, ohne Server bereitstellen oder verwalten zu müssen. AWS Lambda-Erweiterungen bieten eine Möglichkeit, Monitoring-, Beobachtbarkeits-, Sicherheits- und Governance-Tools in die Lambda-Ausführungsumgebung zu integrieren, ohne komplexe Installation oder Konfigurationsverwaltung. Sie können Erweiterungen sowohl als Teil des Laufzeitprozesses mit einer internen Erweiterung als auch als separaten Prozess in der Ausführungsumgebung mit einer externen Erweiterung ausführen.
Lambda-Erweiterungen ermöglichen die Implementierung des Circuit Breaker Pattern ohne Änderung des Kernfunktionscodes. Eine externe Erweiterung prüft in einer separaten Laufzeit, ob ein bestimmter Dienst erreichbar ist oder nicht. Dieser Ansatz entkoppelt die Geschäftslogik in der Lambda-Funktion von der Fehlerermittlung und ermöglicht die Wiederverwendung dieser Lambda-Erweiterung über verschiedene Lambda-Funktionen hinweg. Sowohl die Entkopplung von Code mit unterschiedlichen Zwecken als auch die Wiederverwendbarkeit von Code entsprechen den Best Practices für den Aufbau von Lambda-Funktionen.
Das Pingen eines Microservices bei jedem Lambda-Funktionsaufruf erhöht den Netzwerkverkehr und die Latenz. Implementierungen von Circuit Breakern profitieren von einer Cachingschicht zur Speicherung des Status der Microservices. Die Lambda-Erweiterung ruft den Status eines Microservices aus einer Datenbank ab und speichert das Ergebnis für einen bestimmten Zeitraum im Arbeitsspeicher, um einen Schreibvorgang auf die Datenplatte zu vermeiden. Die Lambda-Funktion prüft den Erweiterungscache, bevor sie den Microservice pingt, wodurch der Netzwerkverkehr reduziert wird. Lambda-Erweiterungen sind ein ideales Werkzeug zum Aufbau eines Cachinglayer für Lambda-Funktionen [EN], da ihr In-Memory-Cache sicherer, einfacher zu verwalten und aufgrund der höheren Verfügbarkeit im Vergleich zum Aufrufen einer Netzwerkressource performanter ist.
Architekturübersicht
- Der Hauptfunktionsprozess verarbeitet das Ereignis nach jedem AWS Lambda-Aufruf. Vor der Ausführung von Aufrufen an externe Komponenten, lauscht er auf HTTP POST-Ereignisse von der Lambda-Erweiterung, um den letzten Circuit Breaker Status der Services abzurufen.
- Die Erweiterung stellt den Circuit Breaker Status für den Hauptprozess über HTTP POST bereit.
- Die Erweiterung prüft ihren internen Cache und gibt einen gültigen Wert zurück, falls vorhanden, andernfalls liest sie den Status aus der DynamoDB-Tabelle und aktualisiert den Cache.
- Schließlich gibt der Erweiterungsprozess den Status an die Hauptfunktion über eine API-Aufrufantwort zurück.
- Aufgrund des Lambda-Erweiterungslebenszyklus erfolgt dieser Prozess periodisch, um den lokalen Cache auf dem neuesten Stand zu halten, bis die Ausführungsumgebung beendet wird.
- Wenn sich der Circuit Breaker Status im Zustand OPEN befindet, führt der Hauptfunktionsprozess Aufrufe gegen die externen Microservices aus, andernfalls gibt der Prozess eine lokale Antwort zurück.
- Ein Amazon EventBridge-Ereignis ruft periodisch eine Lambda auf, die für die Aktualisierung der Circuit Breaker Status verantwortlich ist.
- Diese Lambda-Funktion führt die erforderlichen Validierungen durch, um den Status der verschiedenen Remote-Microservices über einen Amazon API Gateway-Einstiegspunkt zu ermitteln.
- Die Lambda-Funktion schreibt das Ergebnis des Verifikationsprozesses in die DynamoDB-Tabelle.
Schritt für Schritt Anleitung
Für die Durchführung der Schritt-für-Schritt-Anleitung sind folgende Voraussetzungen erforderlich:
- Ein aktives AWS-Konto
- AWS CLI 2.15.17 oder neuer
- AWS SAM CLI 1.116.0 oder neuer
- Git 2.39.3 oder neuer
- Python 3.12
Initiale Einrichtung
- Klonen Sie den Code von GitHub auf Ihren lokalen Rechner:
git clone https://github.com/aws-samples/implementing-the-circuit-breaker-pattern-with-lambda-extensions-and-dynamodb.git
- Um die Pakete zu installieren, verwenden Sie eine virtuelle Umgebung:
python -m venv circuit_breaker_venv && source circuit_breaker_venv/bin/activate
- Um die Dienste für die Bereitstellung vorzubereiten, führen Sie den folgenden AWS Serverless Application Model (SAM)-Befehl aus:
sam build
- Um die Anwendung bereitzustellen, verwenden Sie diesen Befehl und geben Sie das AWS CLI-Profil (in der config-Datei im .aws-Ordner) für das AWS-Konto an, in dem die Anwendung bereitgestellt werden sollen:
sam deploy --guided --profile <AWSProfile>
Der Stackname (new-circuit-breaker-sam-stack) und die Region (us-east-1) können aus der SAM-Konfigurationsdatei (samconfig.toml) übernommen werden.
Wählen Sie N für „Confirm changes before deploy“, Y für „Allow SAM CLI IAM role creation“, N für „Disable rollback“, Y für „MockMicroserviceAPIFunction may not have authorization defined, Is this okay?“ und Y für „Save arguments to configuration file“.
Der Name der SAM-Konfigurationsdatei (samconfig.toml) und die Umgebung (default) können die Standardwerte beibehalten. Jede nachfolgende lokale Codeänderung können Sie wie folgt bereitstellen:
sam build && sam deploy
Testen und Anpassen der Lösung
Amazon DynamoDB ist eine vollständig verwaltete, Serverless-NoSQL-Datenbank, in der der Status der Microservices gespeichert wird. Die Lambda-Funktion, die den Status in DynamoDB aktualisiert, wird wie in der Vorlage angegeben jede Minute ausgeführt. Nachdem die Funktion nach 1 Minute zum ersten Mal ausgeführt wurde, ist der DynamoDB-Eintrag mit dem Status („OPEN“ oder „CLOSED“) bereit. Da die Mock-API Teil des Stacks ist, lautet der Status „OPEN“.
Sie können die Lambda-Funktion „My Microservice“ manuell aufrufen und dieses Ergebnis sehen:
Die Lambda-Funktion zur Aktualisierung des Status in DynamoDB wird über eine EventBridge-Regel aufgerufen, die die URL und die ID des zu überwachenden Dienstes angibt. Durch Erstellen einer neuen EventBridge-Regel mit der korrekten URL und einer neuen ID können Sie die AWS SAM-Vorlage zur Überwachung mehrerer Dienste verwenden.
Um eine neue EventBridge-Regel hinzuzufügen, fügen Sie Folgendes zur Vorlage hinzu:
NewEventRule:
Type: AWS::Events::Rule
Properties:
Description: Event rule to trigger the Lambda function with a JSON payload
ScheduleExpression: rate(1 minute)
State: ENABLED
Targets:
- Arn: !GetAtt UpdatingStateLambda.Arn
Id: TargetFunction
Input: '{ "URL":
"https://thinkwithwp.com/", "ID":
"NewMicroservice"
}' # Add the JSON payload here
MyPermissionForNewEventRule:
Type: AWS::Lambda::Permission
Properties:
FunctionName: !Ref UpdatingStateLambda
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
SourceArn: !GetAtt NewEventRule.Arn
In der Lambda-Funktion, die die Geschäftslogik enthält, fügen Sie die folgenden Umgebungsvariablen hinzu. Bei komplexeren Fällen mit mehreren zu überwachenden Microservices wird jedoch empfohlen, AWS Systems Manager Parameter Store zu verwenden. Mit AWS Systems Manager können Konfigurationen für Lambda-Funktionen gespeichert werden, um eine feinere Kontrolle als mit Umgebungsvariablen zu ermöglichen.
Environment:
Variables:
service_name: "NewMicroservice"
Sie können die Logik dieser Lambda-Funktion anpassen, indem Sie den Code in my-microservice/lambda-handler.py oder direkt im Lambda-Bereich der AWS Management Console ändern.
Wenn Sie Ihre eigene Lambda-Funktion verwenden, um die Circuit Breaker Lambda-Erweiterung zu nutzen, fügen Sie die Erweiterung als Lambda-Layer hinzu:
BusinessLogicMicroservice:
Type: AWS::Serverless::Function
Properties:
CodeUri: business-logic-microservice/
Handler: lambda_function.lambda_handler
MemorySize: 128
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref CircuitBreakerStateTable
Timeout: 100
Runtime: python3.12
Layers:
- !Ref CircuitBreakerExtensionLayer
Circuit Breaker im geschlossenen Zustand
Bisher zeigte die Beispielanwendung nur einen offenen Zustand des Circuit Breaker, der einen funktionierenden Microservice signalisiert. In diesem Abschnitt wird ein nicht reagierender Microservice simuliert, um das Verhalten des Systems mit einem geschlossenen Circuit Breaker Status zu testen. Bearbeiten Sie die Umgebungsvariablen der MyMicroservice Lambda-Funktion in Zeile 47 der template.yaml-Datei und die URL der Eingabe für die Lambda, die den Zustand in der Ereignisregel in Zeile 107 aktualisiert, zu einer Domain, die einen Timeout verursacht, wie z.B. „https://thinkwithwp.com:81/“.
API_URL: "https://thinkwithwp.com:81/"
Input: '{ "URL": "https://thinkwithwp.com:81/", "ID": "MyMicroservice"}'
Stellen Sie diese Änderungen bereit.
sam build && sam deploy
Die Ereignisregel ruft die Lambda-Funktion auf und aktualisiert den Zustand jede Minute. Um die Ausgabe dieser Lambda-Funktion zu sehen, rufen Sie sie manuell auf:
Diese Lambda-Funktion ändert den DynamoDB-Eintrag für diese URL zu
Die MyMicroservice Lambda-Funktion empfängt die DynamoDB-Einträge für den Status über HTTP von der Circuit Breaker Lambda-Erweiterung und fährt mit der Logik nach einem geschlossenen Zustand fort. Die Ausgabe der manuellen Aufrufung der Lambda-Funktion ist:
Dies zeigt, dass das Circuit Breaker Pattern wie beabsichtigt funktioniert. In der Lambda-Funktion, die den Zustand aktualisiert, ist die Zeit, die die Lambda-Funktion benötigt, um eine Timeout-Ausnahme auszulösen, auf 4 Sekunden definiert und kann an den Anwendungsfall angepasst werden.
requests.get(API_URL, headers=headers, timeout=4)
Aufräumen
Um alle Ressourcen aus diesem Stack zu löschen, führen Sie Folgendes aus:
sam delete --stack-name new-circuit-breaker-sam-stack
Sicherheit
Die bereitgestellte SAM-Vorlage stellt keine Amazon Virtual Private Cloud (VPC) bereit, in dem die Ressourcen gehostet werden können. Integrieren Sie die Ressourcen in eine geeignete Netzwerkkonfiguration, wenn sie in Produktionsanwendungen eingesetzt werden.
Aufrufe an den Circuit Breaker und an die Microservices produzieren Logs in Amazon CloudWatch, die mit AWS Key Management Service verschlüsselt werden.
Um die Sicherheit Ihres Kontos mit der Lösung zu überwachen, empfehlen wir die Verwendung von Amazon GuardDuty, AWS CloudTrail, AWS Config und AWS WAF auf der API Gateway.
Fazit
Das Circuit Breaker Pattern ist ein leistungsfähiges Werkzeug zur Gewährleistung der Resilienz und Stabilität von Serverless-Anwendungen. Lambda-Erweiterungen eignen sich gut für dessen Implementierung, wie in diesem Beispiel gezeigt. Mit der bereitgestellten Lambda-Erweiterung und -Funktion können Sie das Circuit Breaker Pattern nahtlos in Ihre Anwendungen integrieren und an Ihre spezifischen Anforderungen anpassen, um ein robustes und zuverlässiges System zu gewährleisten.
Weitere Serverless-Lernressourcen finden Sie auf Serverless Land [EN, Extern].
Über die Autoren
Alan Oberto Jimenez ist Senior Cloud Architekt bei Amazon Web Services (AWS) und ist darauf spezialisiert, Kunden bei der Architektur, Entwicklung und Modernisierung von Anwendungen zu unterstützen, um die Vorteile der AWS-Cloud vollständig nutzen zu können. | |
Tobias Drees ist Cloud-Architekt bei Amazon Web Services (AWS) und hilft Kunden bei der Architektur und Entwicklung von Cloud-Anwendungen. |