Implementieren des serverlosen Saga-Musters mithilfe von AWS Step Functions - AWS Prescriptive Guidance

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.

Implementieren des serverlosen Saga-Musters mithilfe von AWS Step Functions

Erstellt von Tabby Ward (AWS)

: Umwelt PoC oder Pilot

Technologien: Modernisierung; Serverlos; Cloud-nativ

Workload-Aufladung Open Source-Lösung

AWS -Services: AWS CloudFormation; Amazon DynamoDB; Amazon API Gateway; AWS Lambda; AWS Step Functions; Amazon SNS

Summary

In einer Microservices-Architektur besteht das Hauptziel darin, entkoppelte und unabhängige Komponenten zu erstellen, um Agilität, Flexibilität und schnellere Markteinführungszeiten für Ihre Anwendungen zu fördern. Als Ergebnis der Entkopplung hat jede Microservice-Komponente eine eigene Datenpersistenzschicht. In einer verteilten Architektur können Geschäftstransaktionen mehrere Microservices umfassen. Da diese Microservices keine einzelne Atomizität, Konsistenz, Isolation, Dauerhaftigkeit (ACID) -Transaktion verwenden können, können Sie mit Teiltransaktionen enden. In diesem Fall ist eine gewisse Steuerlogik erforderlich, um die bereits verarbeiteten Transaktionen rückgängig zu machen. Zu diesem Zweck wird typischerweise das verteilte Saga Muster verwendet. 

Das Saga-Muster ist ein Fehlerverwaltungsmuster, das hilft, Konsistenz in verteilten Anwendungen herzustellen und Transaktionen zwischen mehreren Microservices zu koordinieren, um die Datenkonsistenz zu gewährleisten. Wenn Sie das Saga-Muster verwenden, veröffentlicht jeder Dienst, der eine Transaktion ausführt, ein Ereignis, das nachfolgende Dienste auslöst, um die nächste Transaktion in der Kette auszuführen. Dies wird fortgesetzt, bis die letzte Transaktion in der Kette abgeschlossen ist. Wenn eine Geschäftstransaktion fehlschlägt, orchestriert Saga eine Reihe von kompensierenden Transaktionen, die die von den vorhergehenden Transaktionen vorgenommenen Änderungen rückgängig machen.

In den folgenden Abschnitten wird veranschaulicht, wie Sie die Einrichtung und Bereitstellung einer Beispielanwendung (die Reisereservierungen verarbeitet) mithilfe des AWS Cloud Development Kit (AWS CDK) zusammen mit serverlosen Technologien wie AWS Step Functions, AWS Lambda und Amazon DynamoDB automatisieren. Die Beispielanwendung verwendet auch Amazon API Gateway und Amazon Simple Notification Service (Amazon SNS), um einen Saga Ausführungskoordinator zu implementieren.

Weitere Informationen zum Saga-Muster und andere Datenpersistenzmuster finden Sie im HandbuchAktivieren von Datenpersistenz in Microservicesauf der AWS Prescriptive Guidance -Website.

Voraussetzungen und Einschränkungen

Voraussetzungen

  • Ein aktives AWS Konto mit programmatischem Zugriff 

  • AWS CDK Toolkit-Stack, der zum Bereitstellen von Ressourcen aus diesem Muster verwendet wird, der in Ihrer AWS Zielregion bereitgestellt wird

  • NodeJS, der für das AWS CDK erforderlich ist

  • AWS CDK CLI mit AWS Kontokonfiguration, sodass Sie AWS-Ressourcen mithilfe dercdk deploy-Befehl

  • Ein Code-Editor Ihrer Wahl (z. B. Visual Studio Code, Sublime oder Atom)

Produktversionen

  • NodeJS Version 14

  • AWS CDK Version 1.89.0

Einschränkungen

Event-Sourcing ist eine natürliche Möglichkeit, das Saga Orchestrierungsmuster in einer Microservices-Architektur zu implementieren, in der alle Komponenten lose gekoppelt sind und keine direkten Kenntnisse voneinander haben. Wenn Ihre Transaktion eine kleine Anzahl von Schritten umfasst (drei bis fünf), könnte das Saga-Muster eine gute Passform sein. Allerdings nimmt die Komplexität mit der Anzahl der Microservices und der Anzahl der Schritte zu. 

Das Testen und Debuggen kann schwierig werden, wenn Sie diesen Entwurf verwenden, da alle Dienste ausgeführt werden müssen, um das Transaktionsmuster zu simulieren.

 

Architecture

Ziel-Architektur

Die vorgeschlagene Architektur verwendet AWS Step Functions, um ein Saga Muster zu erstellen, um Flüge zu buchen, Mietwagen zu buchen und Zahlungen für einen Urlaub zu verarbeiten.

Das folgende Workflow-Diagramm veranschaulicht den typischen Ablauf des Reisereservierungssystems. Der Workflow besteht aus der Reservierung des Flugverkehrs („Reserveflight“), der Reservierung eines Autos („ReserveCarRental“), der Verarbeitung von Zahlungen („ProcessPayment“), der Bestätigung von Flugreservierungen („ConfirmFlight“) und der Bestätigung der Autovermietung („ConfirmCarRental“), gefolgt von einer Erfolgsmeldung, wenn diese Schritte abgeschlossen sind. Wenn das System jedoch Fehler beim Ausführen einer dieser Transaktionen entdeckt, schlägt es rückwärts fehl. Beispielsweise löst ein Fehler bei der Zahlungsverarbeitung („ProcessPayment“) eine Rückerstattung aus („RefundPayment“), die dann eine Stornierung des Mietwagens und des Fluges („CancelRentalReservation“ und „CancelFlightReservation“) auslöst, wodurch die gesamte Transaktion mit einer Fehlermeldung beendet wird.

Dieses Muster stellt separate Lambda Funktionen für jede im Diagramm hervorgehobene Aufgabe sowie drei DynamoDB -Tabellen für Flüge, Mietwagen und Zahlungen bereit. Jede Lambda -Funktion erstellt, aktualisiert oder löscht die Zeilen in den jeweiligen DynamoDB -Tabellen, je nachdem, ob eine Transaktion bestätigt oder zurückgesetzt wird. Das Muster verwendet Amazon SNS, um Textnachrichten (SMS) an Abonnenten zu senden und sie über fehlgeschlagene oder erfolgreiche Transaktionen zu benachrichtigen. 

Automatisierung und Skalierung

Sie können die Konfiguration für diese Architektur mithilfe einer AWS CloudFormation-Vorlage oder AWS CDK-Skripten erstellen. Weitere Informationen finden Sie im Anhang zu den AWS CDK-Skripten, die in TypeScript geschrieben sind.

Tools

AWS-Services

  • AWS Step Functions— AWS Step Functions ist ein serverloser Orchestrierungsservice, mit dem Sie AWS Lambda Funktionen und andere AWS-Services kombinieren können, um geschäftskritische Anwendungen zu erstellen. Über die grafische Konsole „Step Functions“ sehen Sie den Workflow Ihrer Anwendung als eine Reihe ereignisgesteuerter Schritte.

  • Amazon DynamoDB— Amazon DynamoDB ist ein vollständig verwalteter NoSQL Datenbankservice, der schnelle und berechenbare Leistung mit nahtloser Skalierbarkeit bereitstellt. Sie können mit DynamoDB eine Datenbanktabelle erstellen, um beliebige Datenmengen zu speichern und abzurufen und jeglichen Anforderungsdatenverkehr zu verarbeiten.

  • AWS Lambda— AWS Lambda ist ein Datenverarbeitungsservice, mit dem Sie Code ausführen können, ohne Server bereitstellen oder verwalten zu müssen. Lambda führt Ihren Code nur bei Bedarf aus und skaliert automatisch – von einigen Anforderungen pro Tag bis zu Tausenden pro Sekunde.

  • Amazon API Gateway— Amazon API Gateway ist ein AWS -Service zum Erstellen, Veröffentlichen, Überwachen und Sichern von REST-, HTTP-APIs und WebSocket -APIs in jeder Größenordnung.

  • Amazon SNSAmazon Simple Notification Service (Amazon SNS) ist ein verwalteter Service, der Nachrichtenzustellung von Verlagen an Abonnenten bereitstellt.

  • AWS CDK— Das AWS Cloud Development Kit (AWS CDK) ist ein Software-Entwicklungs-Framework zur Definition Ihrer Cloud-Anwendungsressourcen mithilfe vertrauter Programmiersprachen wie TypeScript, JavaScript, Python, Java und C#/Net.

Code

Der Code für eine Beispielanwendung, die das Saga-Muster demonstriert, einschließlich der AWS CDK-Skripte, der Lambda Funktionen und der DynamoDB -Tabellen, ist als Archiv angehängt. Um diese zu installieren, folgen Sie den Anweisungen im ersten Epos.

Epics

AufgabeBeschreibungErforderliche Qualifikationen
Installieren Sie die NPM-Pakete.

Nachdem Sie den Inhalt des angehängten Archivs heruntergeladen und extrahiert haben, führen Sie den folgenden Befehl im Ordner /cdk-serverless-saga aus, um alle NPM-Pakete (Node Package Manager) herunterzuladen und zu installieren:

npm install
Entwickler, Cloud-Architekt
Kompilieren Sie die AWS CDK-Skripte.

Führen Sie im Ordner /cdk-serverless-saga den folgenden Befehl aus, um den TypeScript -Transpiler anzuweisen, alle erforderlichen JavaScript cript-Dateien zu erstellen:

npm run build
Entwickler, Cloud-Architekt
Achten Sie auf Änderungen und kompilieren Sie erneut.

Führen Sie im Ordner /cdk-serverless-saga den folgenden Befehl in einem separaten Terminalfenster aus, um auf Codeänderungen zu achten und den Code zu kompilieren, wenn er eine Änderung erkennt:

npm run watch
Entwickler, Cloud-Architekt
Durchführen von Unit-Tests

Führen Sie im Ordner /cdk-serverless-saga den folgenden Befehl aus, um die Jest-Komponententests durchzuführen:

npm run test
Entwickler, Cloud-Architekt
AufgabeBeschreibungErforderliche Qualifikationen
Stellen Sie den Demo-Stack in AWS bereit.

Führen Sie im Ordner /cdk-serverless-saga den folgenden Befehl aus, um eine Bereitstellungs-Assembly zu erstellen und sie für das standardmäßige AWS Konto und die Region bereitzustellen:

cdk deploy

Dieser Schritt kann einige Minuten dauern. Dieser Befehl verwendet die Standardanmeldeinformationen, die für die AWS Command Line Interface (AWS CLI) konfiguriert wurden. Verwenden Sie den folgenden Befehl, um benannte Profilanmeldeinformationen anzugeben:

cdk deploy --profile <aws_cli_profile_name>

Beachten Sie die API Gateway URL, die nach Abschluss der Bereitstellung auf der Konsole angezeigt wird. Sie benötigen diese Informationen, um den Saga Ausführungsablauf zu testen.

Entwickler, Cloud-Architekt
Vergleichen Sie den bereitgestellten Stack mit dem aktuellen Status.

Führen Sie im Ordner /cdk-serverless-saga den folgenden Befehl aus, um den bereitgestellten Stack mit dem aktuellen Status zu vergleichen, nachdem Sie Änderungen am Quellcode vorgenommen haben:

cdk diff
Entwickler, Cloud-Architekt
Erstellen Sie eine AWS CloudFormation Vorlage.

Führen Sie im Ordner /cdk-serverless-saga den folgenden Befehl aus, um den Stack in eine CloudFormation Vorlage zu synthetisieren:

cdk synth
Entwickler, Cloud-Architekt
AufgabeBeschreibungErforderliche Qualifikationen
Testen Sie den Saga Ausführungsfluss.

Navigieren Sie zu der API Gateway URL, die Sie im vorherigen Schritt bei der Bereitstellung des Stacks notiert haben. Diese URL löst den Start des Zustandscomputers aus. Weitere Informationen dazu, wie Sie den Fluss des Zustandscomputers durch Übergeben verschiedener URL-Parameter manipulieren können, finden Sie in derZusätzliche InformationenAbschnitts erstellt.

Melden Sie sich bei der AWS Management Console an, um die Ergebnisse anzuzeigen, und navigieren Sie zur Step Functions Console. Hier können Sie jeden Schritt der Saga State Machine sehen. Sie können auch die DynamoDB -Tabelle anzeigen, um die eingefügten, aktualisierten oder gelöschten Datensätze anzuzeigen. Wenn Sie den Bildschirm häufig aktualisieren, können Sie beobachten, wie sich der Transaktionsstatus von „Ausstehend“ zu „Bestätigt“ ändert. 

Sie können das SNS-Thema abonnieren, indem Sie den Code in der Datei StateMachine.ts mit Ihrer Mobiltelefonnummer aktualisieren, um SMS-Nachrichten bei erfolgreichen oder fehlgeschlagenen Reservierungen zu empfangen. Weitere Informationen finden Sie unterAmazon SNSimZusätzliche InformationenAbschnitts erstellt.

Entwickler, Cloud-Architekt

Technische Papiere

AWS -Service-Dokumentation

Tutorials

Zusätzliche Informationen

Code

Zu Testzwecken werden in diesem Muster API Gateway und eine TestLambda -Funktion bereitgestellt, die die Statusmaschine „Step Functions“ auslöst. Mit Step Functions können Sie die Funktionalität des Reisereservierungssystems steuern, indem Sie einerun_type-Parameter, um Fehler in „reserveFlight“, „ReserveCarrental“, „ProcessPayment“, „ConfirmFlight“ und „ConfirmCarRental“ nachzuahmen.

Die saga Lambda Funktion (Sagalambda.ts) nimmt Eingaben von den Abfrageparametern in der API Gateway URL an, erstellt das folgende JSON-Objekt und übergibt es zur Ausführung an Step Functions:

let input = { "trip_id": tripID, //  value taken from query parameter, default is AWS request ID "depart_city": "Detroit", "depart_time": "2021-07-07T06:00:00.000Z", "arrive_city": "Frankfurt", "arrive_time": "2021-07-09T08:00:00.000Z", "rental": "BMW", "rental_from": "2021-07-09T00:00:00.000Z", "rental_to": "2021-07-17T00:00:00.000Z", "run_type": runType // value taken from query parameter, default is "success" };

Sie können mit verschiedenen Flows der Statusmaschine „Step Functions“ experimentieren, indem Sie die folgenden URL-Parameter übergeben:

  • Erfolgreiche Ausführung─ https://{api Gateway-URL}

  • Reserve Flight─ https://{api Gateway-URL}?runType=FailFlightsReservation

  • Fehlschlagen des Fluges─ https://{api Gateway-URL}?runType=FailFlightsConfirmation

  • Mietwagen reservieren scheitern─ https://{api Gateway-URL}?runType=FailCarRentalReservation

  • Bestätigen Sie die Autovermietung fehlgeschlagen─ https://{api Gateway-URL}?runType=failcarrentalConfirmation

  • Fehlschlagen der Zahlungsbestätigung─ https://{api Gateway-URL}?runType=FailPayment

  • Übergeben einer Reise-ID─ https://{api Gateway-URL}?TripId={Standardmäßig ist die Reise-ID die AWS Anforderungs-ID}

AWS CDK-Skript

Das angehängte Archiv enthält ein AWS CDK-Skript, mit dem Sie die gesamte Beispielanwendung für Reisereservierungen erstellen können.

DynamoDB-Tabellen

Der angefügte Code erstellt die folgenden DynamoDB -Tabellen. Diese Tabellen enthalten Flugreservierungen, Mietwagenreservierungen und Zahlungsinformationen. 

const flightTable = new dynamodb.Table(this,'Flights',{ partitionKey:{name:'pk', type:dynamodb.AttributeType.STRING}, sortKey:{name:'sk', type: dynamodb.AttributeType.STRING} }) const rentalTable = new dynamodb.Table(this,'Rentals',{ partitionKey:{name:'pk', type:dynamodb.AttributeType.STRING}, sortKey:{name:'sk', type: dynamodb.AttributeType.STRING} }) const paymentTable = new dynamodb.Table(this,'Payments',{ partitionKey:{name:'pk', type:dynamodb.AttributeType.STRING}, sortKey:{name:'sk', type: dynamodb.AttributeType.STRING} }) Flight Data Model: var params = { TableName: process.env.TABLE_NAME, Item: { 'pk' : {S: event.trip_id}, 'sk' : {S: flightReservationID}, 'trip_id' : {S: event.trip_id}, 'id': {S: flightReservationID}, 'depart_city' : {S: event.depart_city}, 'depart_time': {S: event.depart_time}, 'arrive_city': {S: event.arrive_city}, 'arrive_time': {S: event.arrive_time}, 'transaction_status': {S: 'pending'} } }; Car Rental Data Model: var params = { TableName: process.env.TABLE_NAME, Item: { 'pk' : {S: event.trip_id}, 'sk' : {S: carRentalReservationID}, 'trip_id' : {S: event.trip_id}, 'id': {S: carRentalReservationID}, 'rental': {S: event.rental}, 'rental_from': {S: event.rental_from}, 'rental_to': {S: event.rental_to}, 'transaction_status': {S: 'pending'} } }; Payment Data Model: var params = { TableName: process.env.TABLE_NAME, Item: { 'pk' : {S: event.trip_id}, 'sk' : {S: paymentID}, 'trip_id' : {S: event.trip_id}, 'id': {S: paymentID}, 'amount': {S: "750.00"}, // hard coded for simplicity as implementing any monetary transaction functionality is beyond the scope of this pattern 'currency': {S: "USD"}, 'transaction_status': {S: "confirmed"} } };

Lambda-Funktionen

Die folgenden Funktionen werden erstellt, um den Zustand Maschinenfluss und die Ausführung in Step Functions zu unterstützen:

  • Reserve Flight: Fügt einen Datensatz in die DynamoDB Flights -Tabelle mit dem transaction_status ausstehend ein, um einen Flug zu buchen.

  • Bestätigen Sie Flug: Aktualisiert den Datensatz in der DynamoDB Flugtabelle, um transaction_status auf bestätigt zu setzen, um den Flug zu bestätigen.

  • Buchung von Flügen stornieren: Löscht den Datensatz aus der DynamoDB Flugtabelle, um den ausstehenden Flug zu stornieren.

  • Reserve Car Rentals: Fügt einen Datensatz in die DynamoDB CarRentals -Tabelle mit dem transaction_status ausstehend ein, um eine Autovermietung zu buchen.

  • Bestätigen Sie die Autovermietung: Aktualisiert den Datensatz in der DynamoDB CarRentals -Tabelle, um transaction_status auf bestätigt zu setzen, um die Autovermietung zu bestätigen.

  • Reservierung für Mietwagen stornieren: Löscht den Datensatz aus der DynamoDB CarRentals -Tabelle, um die ausstehende Autovermietung zu stornieren.

  • Zahlungsweise: Fügt einen Datensatz in die DynamoDB Payment-Tabelle für die Zahlung ein.

  • Zahlungsbestätigung: Löscht den Datensatz aus der Tabelle DynamoDB Payments für die Zahlung.

let fn = new lambda.Function(scope, id, { runtime: lambda.Runtime.NODEJS_12_X, code: lambda.Code.fromAsset('lambdas'), handler:handler, environment: { TABLE_NAME: table.tableName } });

Amazon SNS

Die Beispielanwendung erstellt das folgende Thema und das folgende Abonnement für das Senden von SMS-Nachrichten und die Benachrichtigung des Kunden über erfolgreiche oder fehlgeschlagene Reservierungen. Wenn Sie beim Testen der Beispielanwendung Textnachrichten erhalten möchten, aktualisieren Sie das SMS-Abonnement mit Ihrer gültigen Telefonnummer in der Datei StateMachine.ts (in der zweiten Zeile des folgenden Codes):

const topic = new  sns.Topic(this, 'Topic'); topic.addSubscription(new subscriptions.SmsSubscription('+11111111111')); const snsNotificationFailure = new tasks.SnsPublish(this ,'SendingSMSFailure', { topic:topic, integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE, message: sfn.TaskInput.fromText('Your Travel Reservation Failed'), });   const snsNotificationSuccess = new tasks.SnsPublish(this ,'SendingSMSSuccess', { topic:topic, integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE, message: sfn.TaskInput.fromText('Your Travel Reservation is Successful'), });

Erfolgreiche Reservierungen

Der folgende Ablauf veranschaulicht eine erfolgreiche Reservierung mit „ReserveFlight“, „ReserveCarRental“ und „ProcessPayment“ gefolgt von „ConfirmFlight“ und „ConfirmCarRental“. Der Kunde wird über die erfolgreiche Buchung durch SMS-Nachrichten benachrichtigt, die an den Abonnenten des SNS-Themas gesendet werden.

Fehlgeschlagene

Dieser Fluss ist ein Beispiel für das Scheitern im Saga-Muster. Wenn nach der Buchung von Flügen und Mietwagen „ProcessPayment“ fehlschlägt, werden die Schritte in umgekehrter Reihenfolge storniert.  Die Reservierungen werden freigegeben, und der Kunde wird über den Fehler durch SMS-Nachrichten benachrichtigt, die an den Abonnenten des SNS-Thema gesendet werden.

Attachments

attachment.zip