Implementare la resilienza delle applicazioni

Completato

Le funzionalità di resilienza di .NET sono basate sul progetto Polly e rese disponibili tramite Microsoft.Extensions. È possibile aggiungere una strategia di resilienza standard che usa impostazioni predefinite sensibili aggiungendo una singola riga di codice all'app.

Aggiungere resilienza all'app

Per aggiungere resilienza a un'app compilata usando un'architettura di microservizi, usare richieste HTTP tra singoli servizi, seguire questa procedura:

  1. Aggiungi il pacchetto Microsoft.Extensions.Http.Resilience al tuo progetto.
  2. Aggiungere un gestore di resilienza alle chiamate al servizio HttpClient.
  3. Configurare la strategia di resilienza.

Aggiungere il pacchetto NuGet al progetto

Eseguire il comando seguente per aggiungere il pacchetto NuGet con resilienza:

dotnet add package Microsoft.Extensions.Http.Resilience

L'esecuzione di questo comando dal terminale nella cartella del progetto app aggiungerà il riferimento al pacchetto al file di progetto.

Aggiungere quindi l'istruzione using seguente nella classe di avvio dell'applicazione:

using Microsoft.Extensions.Http.Resilience;

Aggiungere una strategia di resilienza

È ora possibile aggiungere una strategia di resilienza standard al servizio HttpClient. .NET offre questa configurazione pronta all'uso che combina una serie di strategie.

Diagramma che mostra le strategie incluse nel gestore della resilienza standard. Dal timeout complessivo, riprova, testa bulk, interruttore e tentativo di timeout.

Il gestore delle richieste esegue ognuna di queste strategie in ordine da sinistra a destra:

  • Strategia di timeout totale delle richieste: imposta un periodo totale di tempo che la richiesta può richiedere. Si può pensare a questo come impostare il limite di tempo superiore per tutte le altre strategie.
  • Strategia di ripetizione dei tentativi: Questa strategia controlla le opzioni in base al numero di tentativi, backoff e jitter. Queste opzioni non possono superare il timeout totale impostato nella strategia precedente.
  • Strategia dell'interruttore: Questa strategia apre il circuito se il rapporto di errore supera la soglia.
  • Strategia di timeout dei tentativi: questa strategia imposta un timeout per ogni singola richiesta. Se la richiesta richiede più tempo di questo tempo, viene generata un'eccezione.

È possibile aggiungere questa strategia standard, con tutti i valori predefiniti aggiungendo questo metodo di estensione:

.AddStandardResilienceHandler();

Ad esempio, se è stato dichiarato un WebApplicatione si vuole aggiungere una strategia di resilienza al servizio HttpClient, usare questo codice:

builder.Services.AddHttpClient<ServiceBeingCalled>(httpClient =>
{
    httpClient.BaseAddress = new Uri("https://service.endpoint/");
}).AddStandardResilienceHandler();

La prima riga del codice precedente aggiunge un gestore di resilienza standard a HTTPClient. Verranno usate tutte le impostazioni predefinite per le strategie di ripetizione e interruttore.

Configurare la strategia di resilienza

È possibile modificare i valori predefiniti di una delle strategie specificando nuove opzioni, ad esempio:

.AddStandardResilienceHandler( options => 
{  
    options.RetryOptions.RetryCount = 10;
    options.RetryOptions.BaseDelay = TimeSpan.FromSeconds(1);
});

Questo codice modifica per impostazione predefinita la strategia di ripetizione dei tentativi in modo da avere un numero massimo di ritiri pari a 10, per usare un back off lineare e usare un ritardo di base di 1 secondo.

Le opzioni scelte devono essere compatibili tra loro. Ad esempio, se il tempo totale rimane come predefinito di 30 secondi, le opzioni di ripetizione dei tentativi genereranno un'eccezione. Si tratta di un errore perché l'impostazione del backoff esponenziale determinerebbe la necessità di un tempo complessivo di 2.046 secondi per completare i 10 tentativi. Si tratta di un'eccezione di runtime, non di un errore in fase di compilazione.

Nella tabella seguente sono elencate le opzioni disponibili per ognuna delle strategie.

Opzioni di timeout delle richieste totali Descrizione
TotalTimeout Quantità totale di tempo che la richiesta può richiedere. Il valore predefinito è 30 secondi.
OnTimeout Funzione di callback richiamata al timeout della richiesta. Il valore predefinito è Null.

Opzioni di ripetizione dei tentativi Descrizione
RetryCount Numero massimo di tentativi. Il valore predefinito è 3.
BackoffType Tipo di backoff da utilizzare. È possibile scegliere tra lineare ed esponenziale. Il valore predefinito è esponenziale.
UseJitter Indica se aggiungere jitter al backoff. Il jitter aggiunge casualità al ritardo per ridurre i picchi di carico. Il valore predefinito è vero.
BaseDelay Ritardo tra i tentativi. Il valore predefinito è 2 secondi.

Opzioni dell'interruttore Descrizione
Durata della pausa Durata dell'interruzione del circuito. Il valore predefinito è 5 secondi.
FailureRatio Rapporto tra richieste non riuscite e richieste riuscite che apriranno il circuito. Il valore predefinito è 0.1.
SamplingDuration Durata del tempo in cui viene calcolato il rapporto di errore. Il valore predefinito è 30 secondi.
OnClosed Funzione di callback richiamata quando il circuito viene chiuso. Il valore predefinito è Null.
OnHalfOpened Funzione di callback richiamata quando il circuito è semi-aperto. Il valore predefinito è Null.
OnOpened Funzione di callback richiamata all'apertura del circuito. Il valore predefinito è Null.

Opzioni di timeout tentativo Descrizione
Interruzione temporanea Quantità di tempo che la richiesta può richiedere. Il valore predefinito è 2 secondi.
OnTimeout Funzione di callback richiamata al timeout della richiesta. Il valore predefinito è Null.

Diagramma di sequenza che mostra il flusso di eventi in un'applicazione usando una strategia di resilienza.

Il diagramma di sequenza mostra come ognuna delle strategie interagiscono in una strategia di resilienza standard. Per iniziare, la strategia di timeout totale controlla il fattore di limitazione della durata di una richiesta. La strategia di ripetizione dei tentativi deve quindi essere impostata per avere un numero massimo di tentativi che verranno completati entro il timeout totale. La strategia dell'interruttore aprirà il circuito se il rapporto di errore supera la soglia impostata. La strategia di timeout dei tentativi imposta un timeout per ogni singola richiesta. Se la richiesta richiede più tempo di questo tempo, viene generata un'eccezione.