Schema dell'interruttore - AWS Guida prescrittiva

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à.

Schema dell'interruttore

Intento

Lo schema di interruzione del circuito può impedire a un servizio chiamante di ritentare una chiamata a un altro servizio (chiamante) se in precedenza la chiamata ha causato ripetuti timeout o guasti. Lo schema viene utilizzato anche per rilevare quando il servizio chiamante è di nuovo operativo.

Motivazione

Quando più microservizi collaborano per gestire le richieste, uno o più servizi potrebbero non essere disponibili o presentare una latenza elevata. Quando applicazioni complesse utilizzano microservizi, un'interruzione di un microservizio può causare il fallimento dell'applicazione. I microservizi comunicano tramite chiamate di procedura remote e possono verificarsi errori transitori nella connettività di rete, con conseguenti guasti. (Gli errori transitori possono essere gestiti utilizzando il pattern retry with backoff). Durante l'esecuzione sincrona, la sovrapposizione di timeout o errori può causare un'esperienza utente scadente.

Tuttavia, in alcune situazioni, la risoluzione degli errori potrebbe richiedere più tempo, ad esempio quando il servizio chiamante non è attivo o se un conflitto nel database causa dei timeout. In questi casi, se il servizio chiamante riprova le chiamate ripetutamente, tali tentativi potrebbero causare conflitti di rete e il consumo del pool di thread del database. Inoltre, se più utenti riutilizzano l'applicazione ripetutamente, ciò aggraverà il problema e potrebbe causare un peggioramento delle prestazioni dell'intera applicazione.

Lo schema degli interruttori automatici è stato reso popolare da Michael Nygard nel suo libro Release It (Nygard 2018). Questo modello di progettazione può impedire a un servizio chiamante di ritentare una chiamata di servizio che in precedenza aveva causato ripetuti timeout o guasti. È inoltre in grado di rilevare quando il servizio chiamante è di nuovo operativo.

Gli oggetti dell'interruttore funzionano come interruttori elettrici che interrompono automaticamente la corrente quando si verifica un'anomalia nel circuito. Gli interruttori elettrici interrompono o fanno scattare il flusso di corrente in caso di guasto. Allo stesso modo, l'oggetto interruttore si trova tra il chiamante e il servizio chiamante e interviene se il chiamante non è disponibile.

Gli errori del calcolo distribuito sono un insieme di affermazioni fatte da Peter Deutsch e altri di Sun Microsystems. Dicono che i programmatori che sono nuovi alle applicazioni distribuite invariabilmente formulano false ipotesi. L'affidabilità della rete, le aspettative di latenza zero e le limitazioni della larghezza di banda fanno sì che le applicazioni software siano scritte con una gestione minima degli errori di rete.

Durante un'interruzione della rete, le applicazioni potrebbero attendere una risposta a tempo indeterminato e consumare continuamente le risorse dell'applicazione. La mancata ripetizione delle operazioni quando la rete diventa disponibile può anche portare al degrado delle applicazioni. Se API le chiamate a un database o a un servizio esterno si interrompono a causa di problemi di rete, le chiamate ripetute senza interruttore automatico possono influire sui costi e sulle prestazioni.

Applicabilità

Usa questo schema quando:

  • Il servizio chiamante effettua una chiamata che molto probabilmente non andrà a buon fine.

  • Un'elevata latenza mostrata dal servizio chiamante (ad esempio, quando le connessioni al database sono lente) causa dei timeout per il servizio chiamante.

  • Il servizio chiamante effettua una chiamata sincrona, ma il servizio chiamante non è disponibile o presenta una latenza elevata.

Problemi e considerazioni

  • Implementazione indipendente dal servizio: per evitare il gonfiamento del codice, si consiglia di implementare l'oggetto circuit breaker in modo indipendente dai microservizi e basato sui microservizi. API

  • Chiusura del circuito da parte del chiamante: quando il chiamante si riprende dal problema o dal guasto delle prestazioni, può aggiornare lo stato del circuito a. CLOSED Si tratta di un'estensione dello schema degli interruttori automatici e può essere implementata se l'obiettivo del tempo di ripristino () RTO lo richiede.

  • Chiamate multithread: il valore del timeout di scadenza è definito come il periodo di tempo in cui il circuito rimane attivo prima che le chiamate vengano nuovamente instradate per verificare la disponibilità del servizio. Quando il servizio chiamante viene chiamato in più thread, la prima chiamata non riuscita definisce il valore del timeout di scadenza. L'implementazione deve garantire che le chiamate successive non spostino il timeout di scadenza all'infinito.

  • Apertura o chiusura forzata del circuito: gli amministratori di sistema devono avere la possibilità di aprire o chiudere un circuito. Ciò può essere fatto aggiornando il valore del timeout di scadenza nella tabella del database.

  • Osservabilità: l'applicazione deve avere una registrazione configurata per identificare le chiamate che falliscono quando l'interruttore è aperto.

Implementazione

Architettura di alto livello

Nell'esempio seguente, il chiamante è il servizio ordini e il chiamante è il servizio di pagamento.

In assenza di guasti, il servizio ordini indirizza tutte le chiamate al servizio di pagamento tramite l'interruttore automatico, come illustrato nello schema seguente.

Schema di interruttore automatico senza guasti.

In caso di timeout del servizio di pagamento, l'interruttore automatico è in grado di rilevare il timeout e tracciare l'errore.

Interruttore automatico con guasto del servizio di pagamento.

Se i timeout superano una soglia specificata, l'applicazione apre il circuito. Quando il circuito è aperto, l'oggetto interruttore automatico non indirizza le chiamate al servizio di pagamento. Quando il servizio di ordinazione chiama il servizio di pagamento, restituisce un errore immediato.

L'interruttore automatico interrompe l'indirizzamento al servizio di pagamento.

L'oggetto circuit breaker cerca periodicamente di verificare se le chiamate al servizio di pagamento hanno esito positivo.

Circuit breaker riprova periodicamente il servizio di pagamento.

Quando la chiamata al servizio di pagamento ha esito positivo, il circuito viene chiuso e tutte le altre chiamate vengono nuovamente indirizzate al servizio di pagamento.

Interruttore automatico con servizio di pagamento funzionante.

Implementazione tramite servizi AWS

La soluzione di esempio utilizza flussi di lavoro rapidi AWS Step Functionsper implementare lo schema degli interruttori automatici. La macchina a stati Step Functions consente di configurare le funzionalità di riprova e il flusso di controllo basato sulle decisioni necessari per l'implementazione del modello.

La soluzione utilizza anche una tabella Amazon DynamoDB come archivio dati per tenere traccia dello stato del circuito. Questo può essere sostituito con un datastore in memoria come Amazon ElastiCache (RedisOSS) per prestazioni migliori.

Quando un servizio desidera chiamare un altro servizio, avvia il flusso di lavoro con il nome del servizio chiamante. Il flusso di lavoro ottiene lo stato dell'interruttore automatico dalla tabella CircuitStatus DynamoDB, che memorizza i servizi attualmente danneggiati. Se CircuitStatus contiene un record non scaduto per il chiamante, il circuito è aperto. Il flusso di lavoro Step Functions restituisce un errore immediato e termina con uno FAIL stato.

Se la CircuitStatus tabella non contiene un record per il chiamante o contiene un record scaduto, il servizio è operativo. Il ExecuteLambda passaggio nella definizione della macchina a stati richiama la funzione Lambda che viene inviata tramite un valore di parametro. Se la chiamata ha esito positivo, il flusso di lavoro Step Functions termina con uno SUCCESS stato.

Implementazione di interruttori automatici con AWS Step Functions e DynamoDB.

Se la chiamata di servizio fallisce o si verifica un timeout, l'applicazione riprova con un backoff esponenziale per un numero definito di volte. Se la chiamata di servizio fallisce dopo i nuovi tentativi, il flusso di lavoro inserisce un record nella CircuitStatus tabella del servizio con l'an ExpiryTimeStamp e il flusso di lavoro termina con uno stato. FAIL Le chiamate successive allo stesso servizio restituiscono un errore immediato finché l'interruttore è aperto. La Get Circuit Status fase di definizione della macchina a stati verifica la disponibilità del servizio in base al ExpiryTimeStamp valore. Gli elementi scaduti vengono eliminati dalla CircuitStatus tabella utilizzando la funzionalità time to live () di DynamoDB. TTL

Codice di esempio

Il codice seguente utilizza la funzione GetCircuitStatus Lambda per controllare lo stato dell'interruttore.

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

Il codice seguente mostra le istruzioni di Amazon States Language nel flusso di lavoro Step Functions.

"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

Per un'implementazione completa dell'architettura di esempio per questo modello, consulta il GitHub repository all'indirizzo. https://github.com/aws-samples/circuit-breaker-netcore-blog

Riferimenti del blog

Contenuti correlati