Condividi tramite


Implementare i tentativi di chiamata HTTP con backoff esponenziale utilizzando i criteri di IHttpClientFactory e Polly.

Suggerimento

Questo contenuto è un estratto dell'eBook, Architettura di microservizi .NET per applicazioni .NET containerizzati, disponibile in documentazione .NET o come PDF scaricabile gratuitamente leggibile offline.

Architettura di Microservizi .NET per Applicazioni .NET Containerizzate miniatura della copertina dell'eBook.

L'approccio consigliato per i tentativi di ripetizione con backoff esponenziale consiste nello sfruttare le librerie .NET più avanzate come la libreria Polly open source.

Polly è una libreria .NET che offre funzionalità di resilienza e gestione degli errori temporanei. È possibile implementare queste funzionalità applicando i criteri di Polly, ad esempio Riprovare, Interruttore automatico, Isolamento compartimentato, Timeout e Fallback. Polly è destinato a .NET Framework 4.x e .NET Standard 1.0, 1.1 e 2.0 (che supporta .NET Core e versioni successive).

I passaggi seguenti illustrano come utilizzare i tentativi di ripetizione HTTP con Polly integrato in IHttpClientFactory, come illustrato nella sezione precedente.

Installare pacchetti .NET

Prima di tutto, è necessario installare il Microsoft.Extensions.Http.Polly pacchetto.

Fare riferimento ai pacchetti .NET 8

IHttpClientFactory è disponibile a partire da .NET Core 2.1, tuttavia, è consigliabile usare i pacchetti .NET 8 più recenti di NuGet nel progetto. In genere è anche necessario fare riferimento al pacchetto Microsoft.Extensions.Http.Pollydi estensione .

Configura un client con la politica di Retry di Polly, all'avvio dell'applicazione

Il metodo AddPolicyHandler() consente di aggiungere criteri agli HttpClient oggetti che verranno usati. In questo caso, si tratta di aggiungere una policy di Polly per i tentativi HTTP con backoff esponenziale.

Per avere un approccio più modulare, i criteri di ripetizione http possono essere definiti in un metodo separato all'interno del file Program.cs , come illustrato nel codice seguente:

static IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
{
    return HttpPolicyExtensions
        .HandleTransientHttpError()
        .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
        .WaitAndRetryAsync(6, retryAttempt => TimeSpan.FromSeconds(Math.Pow(2,
                                                                    retryAttempt)));
}

Come illustrato nelle sezioni precedenti, è necessario definire una configurazione HttpClient client denominata o tipizzata nella configurazione standard dell'app Program.cs . A questo punto si aggiunge codice aggiuntivo che specifica i criteri per i tentativi HTTP con backoff esponenziale, come indicato di seguito:

// Program.cs
builder.Services.AddHttpClient<IBasketService, BasketService>()
        .SetHandlerLifetime(TimeSpan.FromMinutes(5))  //Set lifetime to five minutes
        .AddPolicyHandler(GetRetryPolicy());

Con Polly è possibile definire un criterio di ripetizione dei tentativi con il numero di tentativi, la configurazione di backoff esponenziale e le azioni da eseguire quando si verifica un'eccezione HTTP, ad esempio la registrazione dell'errore. In questo caso, i criteri sono configurati per provare sei volte con un nuovo tentativo esponenziale, a partire da due secondi.

Aggiungere una strategia di instabilità ai criteri di ripetizione dei tentativi

Una politica di ritentativo regolare può influire sul sistema in situazioni di alta concorrenza e scalabilità e sotto forte contesa. Per superare i picchi di tentativi simili provenienti da molti client durante interruzioni parziali, una buona soluzione alternativa consiste nell'aggiungere una strategia di jitter all'algoritmo/politica di ripetizione dei tentativi. Questa strategia può migliorare le prestazioni complessive del sistema end-to-end. Come consigliato in Polly: Riprovare con jitter, una buona strategia di jitter può essere implementata da intervalli di riprova uniformi e ben distribuiti applicati con un ritardo iniziale di riprova ben controllato con un backoff esponenziale. Questo approccio consente di distribuire i picchi quando si verifica il problema. Il principio è illustrato nell'esempio seguente:


var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5);

var retryPolicy = Policy
    .Handle<FooException>()
    .WaitAndRetryAsync(delay);

Risorse aggiuntive