Implementowanie ponownych prób wywołań HTTP z wycofywaniem wykładniczym przy użyciu zasad IHttpClientFactory i Polly

Napiwek

Ta zawartość jest fragmentem książki eBook, architektury mikrousług platformy .NET dla konteneryzowanych aplikacji platformy .NET dostępnych na platformie .NET Docs lub jako bezpłatnego pliku PDF, który można odczytać w trybie offline.

.NET Microservices Architecture for Containerized .NET Applications eBook cover thumbnail.

Zalecaną metodą ponawiania prób z wycofywaniem wykładniczym jest wykorzystanie bardziej zaawansowanych bibliotek platformy .NET, takich jak biblioteka Polly typu open source.

Polly to biblioteka platformy .NET, która zapewnia odporność i możliwości obsługi błędów przejściowych. Te możliwości można zaimplementować, stosując zasady sondowania, takie jak ponawianie prób, wyłącznik, izolacja grodziowa, przekroczenie limitu czasu i rezerwa. Usługa Polly jest przeznaczona dla programów .NET Framework 4.x i .NET Standard 1.0, 1.1 i 2.0 (które obsługują platformę .NET Core i nowsze).

W poniższych krokach pokazano, jak można użyć ponownych prób protokołu Http z usługą Polly zintegrowanej z usługą IHttpClientFactory, co zostało wyjaśnione w poprzedniej sekcji.

Instalowanie pakietów .NET

Najpierw należy zainstalować Microsoft.Extensions.Http.Polly pakiet.

Odwołanie do pakietów platformy .NET 8

IHttpClientFactory jest dostępna od wersji .NET Core 2.1, jednak zalecamy użycie najnowszych pakietów platformy .NET 8 z pakietu NuGet w projekcie. Zazwyczaj należy również odwołać się do pakietu Microsoft.Extensions.Http.Pollyrozszerzenia .

Konfigurowanie klienta przy użyciu zasad ponawiania próby usługi Polly podczas uruchamiania aplikacji

Metoda AddPolicyHandler() dodaje zasady do obiektów, których będziesz używaćHttpClient. W tym przypadku jest to dodanie zasad polly dla ponawiania prób http z wykładniczym wycofywaniem.

Aby zapewnić bardziej modułowe podejście, zasady ponawiania http można zdefiniować w oddzielnej metodzie w pliku Program.cs , jak pokazano w poniższym kodzie:

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

Jak pokazano w poprzednich sekcjach, należy zdefiniować konfigurację klienta HttpClient o nazwie lub typie w standardowej konfiguracji aplikacji Program.cs . Teraz dodasz kod przyrostowy określający zasady dla ponownych prób http z wycofywaniem wykładniczym w następujący sposób:

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

Za pomocą usługi Polly można zdefiniować zasady ponawiania z liczbą ponownych prób, konfiguracją wycofywania wykładniczego i akcjami, które należy wykonać w przypadku wystąpienia wyjątku HTTP, takiego jak rejestrowanie błędu. W takim przypadku zasady są skonfigurowane do próby sześciokrotnie przy użyciu ponawiania wykładniczego, począwszy od dwóch sekund.

Dodawanie strategii zakłócenia do zasad ponawiania prób

Regularne zasady ponawiania prób mogą mieć wpływ na system w przypadkach wysokiej współbieżności i skalowalności oraz w przypadku wysokiej rywalizacji. Aby przezwyciężyć szczyty podobnych ponownych prób pochodzących z wielu klientów w częściowych przestojach, dobrym obejściem jest dodanie strategii mieszania do algorytmu/zasad ponawiania prób. Ta strategia może poprawić ogólną wydajność kompleksowego systemu. Zgodnie z zaleceniami w polly: Ponów próbę z jitter, dobra strategia zakłóceń może być zaimplementowana przez płynne i równomiernie rozproszone interwały ponawiania prób stosowane z dobrze kontrolowanym opóźnieniem początkowego ponawiania prób na wycofywaniu wykładniczym. Takie podejście pomaga rozłożyć skoki po wystąpieniu problemu. Zasada jest zilustrowana następującym przykładem:


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

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

Dodatkowe zasoby