Udostępnij za pośrednictwem


Implementacja ponownych prób wywołań HTTP z eksponencjalnym backoffem przy użyciu IHttpClientFactory i zasad Polly

Wskazówka

Ta treść jest fragmentem eBooka "Architektura mikrousług .NET dla konteneryzowanych aplikacji .NET", dostępnego na .NET Docs lub jako bezpłatny plik PDF do pobrania i czytania w trybie offline.

Miniatura okładki eBooka „Architektura mikrousług platformy .NET dla konteneryzowanych aplikacji platformy .NET”.

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. Można zaimplementować te możliwości, stosując zasady Polly, takie jak ponowienie, przerywacz obwodu, izolacja przegrody, przekroczenie limitu czasu i alternatywy. 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.

Referencje do pakietów .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.Polly rozszerzenia.

Skonfiguruj klienta z polityką ponawiania prób Polly podczas startu aplikacji

Metoda AddPolicyHandler() dodaje zasady do obiektów, których będziesz używać HttpClient . W tym przypadku jest to dodanie polityki Polly dla ponownych prób HTTP z wykładniczym opóźnieniem.

Aby zapewnić bardziej modułowe podejście, polityka ponawiania żądań HTTP może być zdefiniowana w oddzielnej metodzie w pliku Program.cs, co 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 z nazwą lub typem 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ą narzędzia Polly można zdefiniować politykę ponawiania z określoną liczbą prób, konfiguracją wykładniczego zmniejszania interwałów oraz działaniami do podjęcia w przypadku wystąpienia wyjątku HTTP, takimi jak rejestrowanie błędu. W takim przypadku polityka jest skonfigurowana do sześciu prób z wykładniczym ponawianiem, zaczynając od dwóch sekund.

Dodaj strategię losowej zmienności do polityki 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 zminimalizować szczyty podobnych ponownych prób pochodzących od wielu klientów podczas częściowych przestojów, dobrym rozwiązaniem jest dodanie strategii jitter do algorytmu/polityki 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