Implementa il modello di saga serverless utilizzando Step Functions AWS - Prontuario AWS

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

Implementa il modello di saga serverless utilizzando Step Functions AWS

Creato da Tabby Ward (AWS), Rohan Mehta () e Rimpy Tewani () AWS AWS

Ambiente: PoC o pilota

Tecnologie: modernizzazione; serverless

Carico di lavoro: open source

AWSservizi: Amazon API Gateway; Amazon DynamoDB; LambdaAWS; Amazon; Step Functions SNS AWS

Riepilogo

In un'architettura di microservizi, l'obiettivo principale è creare componenti disaccoppiati e indipendenti per promuovere agilità, flessibilità e tempi di commercializzazione più rapidi per le applicazioni. Come risultato del disaccoppiamento, ogni componente dei microservizi ha il proprio livello di persistenza dei dati. In un'architettura distribuita, le transazioni commerciali possono estendersi su più microservizi. Poiché questi microservizi non possono utilizzare una singola transazione di atomicità, coerenza, isolamento, durabilità (ACID), è possibile che si ottengano transazioni parziali. In questo caso, è necessaria una certa logica di controllo per annullare le transazioni che sono già state elaborate. Il modello a saga distribuito viene in genere utilizzato per questo scopo. 

Il modello a saga è un modello di gestione degli errori che aiuta a stabilire la coerenza nelle applicazioni distribuite e coordina le transazioni tra più microservizi per mantenere la coerenza dei dati. Quando si utilizza il modello saga, ogni servizio che esegue una transazione pubblica un evento che attiva i servizi successivi per eseguire la transazione successiva nella catena. Questo continua fino al completamento dell'ultima transazione della catena. Se una transazione commerciale fallisce, saga orchestra una serie di transazioni di compensazione che annullano le modifiche apportate dalle transazioni precedenti.

Questo modello dimostra come automatizzare la configurazione e la distribuzione di un'applicazione di esempio (che gestisce le prenotazioni di viaggi) con tecnologie serverless come AWS Step Functions, AWS Lambda e Amazon DynamoDB. L'applicazione di esempio utilizza anche Amazon API Gateway e Amazon Simple Notification Service (AmazonSNS) per implementare un coordinatore dell'esecuzione di saga. Il pattern può essere implementato con un framework Infrastructure as Code (IaC) come AWS Cloud Development Kit (AWSCDK), AWS Serverless Application Model (AWSSAM) o Terraform.

Per ulteriori informazioni sul modello saga e su altri modelli di persistenza dei dati, consulta la guida Enabling data persistence in microservices sul sito Web Prescriptive Guidance. AWS

Prerequisiti e limitazioni

Prerequisiti

  • Un account AWS attivo.

  • Autorizzazioni per creare uno stack. AWS CloudFormation Per ulteriori informazioni, consulta Controllo dell'accesso nella CloudFormation documentazione.

  • Framework IaC di tua scelta (AWSCDKo Terraform) configurato con il tuo AWS account in modo da poter utilizzare il framework CLI per distribuire l'applicazione. AWS SAM

  • NodeJS, utilizzato per creare l'applicazione ed eseguirla localmente.

  • Un editor di codice a tua scelta (come Visual Studio Code, Sublime o Atom).

Versioni del prodotto

Limitazioni

L'event sourcing è un modo naturale per implementare il modello di orchestrazione della saga in un'architettura di microservizi in cui tutti i componenti sono liberamente accoppiati e non hanno una conoscenza diretta l'uno dell'altro. Se la transazione prevede un numero limitato di passaggi (da tre a cinque), il modello a saga potrebbe essere la soluzione ideale. Tuttavia, la complessità aumenta con il numero di microservizi e il numero di passaggi. 

Il test e il debug possono diventare difficili quando si utilizza questo design, poiché è necessario che tutti i servizi siano in esecuzione per simulare il modello di transazione.

Architettura

Architettura di Target

L'architettura proposta utilizza AWS Step Functions per creare uno schema a saga per prenotare voli, prenotare auto a noleggio ed elaborare i pagamenti per una vacanza.

Il seguente diagramma del flusso di lavoro illustra il flusso tipico del sistema di prenotazione viaggi. Il flusso di lavoro consiste nella prenotazione dei viaggi aerei («ReserveFlight»), nella prenotazione di un'auto («ReserveCarRental»), nell'elaborazione dei pagamenti («ProcessPayment»), nella conferma delle prenotazioni dei voli («ConfirmFlight») e nella conferma del noleggio auto («ConfirmCarRental»), seguite da una notifica di avvenuto completamento di questi passaggi. Tuttavia, se il sistema riscontra errori nell'esecuzione di una di queste transazioni, inizia a fallire all'indietro. Ad esempio, un errore nell'elaborazione dei pagamenti («ProcessPayment») attiva un rimborso («RefundPayment»), che quindi attiva la cancellazione dell'auto a noleggio e del volo («CancelRentalReservation» e «CancelFlightReservation»), che termina l'intera transazione con un messaggio di errore.

Questo modello implementa funzioni Lambda separate per ogni attività evidenziata nel diagramma, oltre a tre tabelle DynamoDB per voli, autonoleggi e pagamenti. Ogni funzione Lambda crea, aggiorna o elimina le righe nelle rispettive tabelle DynamoDB, a seconda che una transazione sia confermata o ripristinata. Il modello utilizza Amazon SNS per inviare messaggi di testo (SMS) agli abbonati, avvisandoli delle transazioni non riuscite o riuscite. 

Flusso di lavoro per un sistema di prenotazione viaggi basato sullo schema della saga.

Automazione e scalabilità

È possibile creare la configurazione per questa architettura utilizzando uno dei framework IaC. Usa uno dei seguenti link per il tuo IAc preferito.

Strumenti

AWSservizi

  • AWSStep Functions è un servizio di orchestrazione serverless che consente di combinare funzioni AWS Lambda e altri AWS servizi per creare applicazioni aziendali critiche. Attraverso la console grafica Step Functions, puoi vedere il flusso di lavoro dell'applicazione come una serie di passaggi guidati dagli eventi.

  • Amazon DynamoDB è un servizio di database SQL No completamente gestito che offre prestazioni veloci e prevedibili con una scalabilità perfetta. Puoi utilizzare DynamoDB per creare una tabella di database in grado di archiviare e recuperare qualunque quantità di dati e soddisfare qualsiasi livello di traffico di richiesto.

  • AWSLambda è un servizio di elaborazione che consente di eseguire codice senza effettuare il provisioning o gestire server. Lambda esegue il codice solo quando è necessario e si dimensiona automaticamente, da poche richieste al giorno a migliaia al secondo.

  • Amazon API Gateway è un AWS servizio per la creazione, la pubblicazione, la manutenzione, il monitoraggio e la protezione RESTHTTP, WebSocket APIs su qualsiasi scala.

  • Amazon Simple Notification Service (AmazonSNS) è un servizio gestito che fornisce il recapito dei messaggi dagli editori agli abbonati.

  • AWSCloud Development Kit (AWSCDK) è un framework di sviluppo software per definire le risorse delle applicazioni cloud utilizzando linguaggi di programmazione familiari come Python TypeScript JavaScript, Java e C#/.Net.

  • AWSServerless Application Model (AWSSAM) è un framework open source per la creazione di applicazioni serverless. Fornisce una sintassi abbreviata per esprimere funzioni, database e mappature delle sorgenti degli APIs eventi.

Codice

Il codice per un'applicazione di esempio che dimostra il modello saga, incluso il modello IAc (AWSCDK, o Terraform) AWSSAM, le funzioni Lambda e le tabelle DynamoDB, è disponibile nei seguenti link. Segui le istruzioni del primo capitolo epico per installarli.

Epiche

AttivitàDescrizioneCompetenze richieste

Installa i NPM pacchetti.

Crea una nuova directory, accedi a quella directory in un terminale e clona il GitHub repository di tua scelta dalla sezione Codice precedente in questo schema.

Nella cartella principale che contiene il package.json file, esegui il seguente comando per scaricare e installare tutti i pacchetti Node Package Manager (NPM):

npm install
Sviluppatore, architetto cloud

Compila script.

Nella cartella principale, esegui il seguente comando per indicare al TypeScript transpiler di creare tutti i file necessari: JavaScript

npm run build
Sviluppatore, architetto cloud

Controlla le modifiche e ricompila.

Nella cartella principale, esegui il seguente comando in una finestra di terminale separata per controllare le modifiche al codice e compila il codice quando rileva una modifica:

npm run watch
Sviluppatore, architetto cloud

Esegui (AWSCDKsolo) test unitari.

Se stai usando AWSCDK, nella cartella principale, esegui il seguente comando per eseguire i test unitari di Jest:

npm run test
Sviluppatore, architetto cloud
AttivitàDescrizioneCompetenze richieste

Distribuisci lo stack demo su. AWS

Importante: l'applicazione è AWS indipendente dalla regione. Se si utilizza un profilo, è necessario dichiarare la regione in modo esplicito nel profilo AWSCommand Line Interface (AWSCLI) o tramite variabili di ambiente. AWS CLI

Nella cartella principale, esegui il comando seguente per creare un assembly di distribuzione e distribuirlo nell'AWSaccount e nella regione predefiniti.

AWS CDK:

cdk bootstrap cdk deploy

AWS SAM:

sam build sam deploy --guided

Terraform:

terraform init terraform apply

Il completamento di questo passaggio potrebbe richiedere alcuni minuti. Questo comando utilizza le credenziali predefinite configurate per. AWS CLI

Nota il API Gateway URL che viene visualizzato sulla console al termine della distribuzione. Avrai bisogno di queste informazioni per testare il flusso di esecuzione della saga.

Sviluppatore, architetto cloud

Confronta lo stack distribuito con lo stato attuale.

Nella cartella principale, esegui il comando seguente per confrontare lo stack distribuito con lo stato corrente dopo aver apportato modifiche al codice sorgente:

AWS CDK:

cdk diff

AWS SAM:

sam deploy

Terraform:

terraform plan
Sviluppatore, architetto cloud
AttivitàDescrizioneCompetenze richieste

Metti alla prova il flusso di esecuzione della saga.

Passa al API Gateway URL che hai annotato nel passaggio precedente, quando hai distribuito lo stack. Ciò URL attiva l'avvio della macchina a stati. Per ulteriori informazioni su come manipolare il flusso della macchina a stati passando URL parametri diversi, vedere la sezione Informazioni aggiuntive.

Per visualizzare i risultati, accedi alla console di AWS gestione e vai alla console Step Functions. Qui puoi vedere ogni fase della saga state machine. Puoi anche visualizzare la tabella DynamoDB per vedere i record inseriti, aggiornati o eliminati. Se aggiorni spesso la schermata, puoi vedere lo stato della transazione cambiare da a. pending confirmed 

Puoi iscriverti all'SNSargomento aggiornando il codice nel stateMachine.ts file con il tuo numero di cellulare per ricevere SMS messaggi in caso di prenotazioni riuscite o fallite. Per ulteriori informazioni, consulta Amazon SNS nella sezione Informazioni aggiuntive.

Sviluppatore, architetto cloud
AttivitàDescrizioneCompetenze richieste

Pulisci le risorse.

Per pulire le risorse distribuite per questa applicazione, è possibile utilizzare uno dei seguenti comandi.

AWS CDK:

cdk destroy

AWS SAM:

sam delete

Terraform:

terraform destroy
Sviluppatore di app, architetto cloud

Risorse correlate

Documenti tecnici

AWSdocumentazione di servizio

Tutorial

Informazioni aggiuntive

Codice

A scopo di test, questo modello implementa API Gateway e una funzione Lambda di test che attiva la macchina a stati Step Functions. Con Step Functions, puoi controllare la funzionalità del sistema di prenotazione viaggi passando un run_type parametro per simulare gli errori in «ReserveFlightReserveCarRental,» «ProcessPayment,»,» e «ConfirmFlightConfirmCarRental.»

La funzione saga Lambda (sagaLambda.ts) riceve l'input dai parametri di interrogazione nel API GatewayURL, crea il seguente JSON oggetto e lo passa a Step Functions per l'esecuzione:

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" };

È possibile sperimentare diversi flussi della macchina a stati Step Functions passando i seguenti URL parametri:

  • Esecuzione riuscita ─ https://{api gateway url}

  • Reserve Flight Fail ─ https://{api gateway url}? runType= failFlightsReservation

  • Conferma Flight Fail ─ https://{api gateway url}? runType= failFlightsConfirmation

  • Prenotazione auto fallita ─ https://{api gateway url}? runType= failCarRental Prenotazione

  • Conferma il fallimento del noleggio auto ─ https://{api gateway url}? runType= failCarRental Conferma

  • Processo di pagamento non riuscito ─ https://{api gateway url}? runType= failPayment

  • Passa un Trip ID ─ https://{api gateway url}? tripId= {per impostazione predefinita, l'ID del viaggio sarà l'ID della AWS richiesta}

modelli IaC

Gli archivi collegati includono modelli IaC che è possibile utilizzare per creare l'intera applicazione di prenotazione viaggi di esempio.

Tabelle DynamoDB

Ecco i modelli di dati per le tabelle dei voli, degli autonoleggi e dei pagamenti.

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"} } };

Funzioni Lambda

Verranno create le seguenti funzioni per supportare il flusso e l'esecuzione della macchina a stati in Step Functions:

  • Reserve Flights: inserisce un record nella tabella DynamoDB Flights con transaction_status un pending di, per prenotare un volo.

  • Confirm Flight: aggiorna il record nella tabella DynamoDB Flights, da transaction_status impostare su, per confermare confirmed il volo.

  • Annulla prenotazione voli: elimina il record dalla tabella DynamoDB Flights, per annullare il volo in sospeso.

  • Reserve Car Rentals: inserisce un record nella tabella CarRentals DynamoDB con transaction_status un pending di, per prenotare un noleggio auto.

  • Conferma noleggio auto: aggiorna il record nella tabella CarRentals DynamoDB, transaction_status impostandolo su, per confermare confirmed il noleggio auto.

  • Annulla prenotazione noleggio auto: elimina il record dalla tabella CarRentals DynamoDB, per annullare il noleggio auto in sospeso.

  • Elabora pagamento: inserisce un record nella tabella Pagamenti di DynamoDB per il pagamento.

  • Annulla pagamento: elimina il record del pagamento dalla tabella DynamoDB Payments.

Amazon SNS

L'applicazione di esempio crea il seguente argomento e sottoscrizione per l'invio di SMS messaggi e la notifica al cliente in caso di prenotazioni andate a buon fine o non riuscite. Se desideri ricevere messaggi di testo durante il test dell'applicazione di esempio, aggiorna l'SMSabbonamento con il tuo numero di telefono valido nel file di definizione della macchina a stati.

AWSCDKsnippet (aggiungi il numero di telefono nella seconda riga del codice seguente):

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'), });

AWSSAMsnippet (sostituisci le +1111111111 stringhe con il tuo numero di telefono valido):

StateMachineTopic11111111111: Type: 'AWS::SNS::Subscription' Properties: Protocol: sms TopicArn: Ref: StateMachineTopic Endpoint: '+11111111111' Metadata: 'aws:sam:path': SamServerlessSagaStack/StateMachine/Topic/+11111111111/Resource

Terraform snippet (sostituisci la +111111111 stringa con il tuo numero di telefono valido):

resource "aws_sns_topic_subscription" "sms-target" { topic_arn = aws_sns_topic.topic.arn protocol = "sms" endpoint = "+11111111111" }

Prenotazioni riuscite

Il seguente flusso illustra una prenotazione riuscita con «ReserveFlight,»» e «ReserveCarRentalProcessPayment» seguiti da «ConfirmFlight» e «ConfirmCarRental.» Il cliente viene informato dell'avvenuta prenotazione tramite SMS messaggi inviati all'abbonato dell'SNSargomento.

Esempio di prenotazione riuscita implementata da Step Functions utilizzando il modello saga.

Prenotazioni non riuscite

Questo flusso è un esempio di fallimento dello schema della saga. Se, dopo aver prenotato voli e auto a noleggio, «ProcessPayment» fallisce, i passaggi vengono annullati in ordine inverso.  Le prenotazioni vengono rilasciate e il cliente viene informato dell'errore tramite SMS messaggi inviati all'abbonato dell'argomento. SNS

Esempio di prenotazione fallita implementata da Step Functions utilizzando il modello saga.