Implementieren von Wiederholungen von HTTP-Aufrufen mit exponentiellem Backoff mit IHttpClientFactory und Polly-Richtlinien

Tipp

Diese Inhalte sind ein Auszug aus dem eBook „.NET Microservices Architecture for Containerized .NET Applications“, verfügbar unter .NET Docs oder als kostenlos herunterladbare PDF-Datei, die offline gelesen werden kann.

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

Für Wiederholungen mit exponentiellem Backoff wird empfohlen, fortgeschrittenere .NET-Bibliotheken wie die Open Source-Bibliothek Polly zu verwenden.

Polly ist eine .NET-Bibliothek, die Funktionen für die Flexibilität und die Behandlung von vorübergehenden Fehlern bereitstellt. Sie können diese Funktionen implementieren, indem Sie Polly-Richtlinien wie „Retry“, „Circuit Breaker“, „Bulkhead Isolation“, „Timeout“, und „Fallback“ anwenden. Polly unterstützt .NET Framework 4.x und .NET Standard 1.0, 1.1 und 2.0 (unterstützt .NET Core und höher).

Die folgenden Schritte veranschaulichen, wie Sie HTTP-Wiederholungen mit Polly in IHttpClientFactory verwenden können. Die Integration von Polly wird im vorherigen Abschnitt erläutert.

Installieren von .NET-Paketen

Zuerst müssen Sie das Microsoft.Extensions.Http.Polly-Paket installieren.

Verweisen auf die .NET 8-Pakete

IHttpClientFactory ist seit .NET Core 2.1 verfügbar. Wir empfehlen jedoch die Verwendung der neuesten .NET 8-Pakete auf NuGet in Ihrem Projekt. In der Regel müssen Sie auch auf das Erweiterungspaket Microsoft.Extensions.Http.Polly verweisen.

Konfigurieren eines Clients mit der Wiederholungsrichtlinie von Polly beim App-Start

Durch die Methode AddPolicyHandler() werden Richtlinien zu HttpClient-Objekten hinzugefügt, die Sie verwenden werden. In diesem Fall wird eine Richtlinie von Polly für HTTP-Wiederholungen mit exponentiellem Backoff hinzugefügt.

Für einen modulareren Ansatz kann die HTTP-Wiederholungsrichtlinie in einer separaten Methode innerhalb der Program.cs-Datei definiert werden. Dies wird im folgenden Code veranschaulicht:

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

Wie in den vorherigen Abschnitten gezeigt, müssen Sie eine HttpClient-Konfiguration mit benanntem oder typisierten Client in Ihrer standardmäßigen Program.cs-App-Konfiguration definieren. Jetzt fügen Sie wie folgt inkrementellen Code hinzu, der die Richtlinie für die HTTP-Wiederholungen mit exponentiellem Backoff angibt:

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

Mit Polly können Sie eine Wiederholungsrichtlinie definieren, die die Anzahl von Wiederholungen, die Konfiguration des exponentiellen Backoffs und die Aktionen enthält, die ausgeführt werden, wenn eine HTTP-Ausnahme ausgelöst wird, z.B. die Protokollierung des Fehlers. In diesem Fall ist die Richtlinie dafür konfiguriert, sechs Versuche mit einer exponentiellen Wiederholung durchzuführen, die bei zwei Sekunden beginnt.

Hinzufügen einer Jitterstrategie zur Wiederholungsrichtlinie

Eine reguläre Wiederholungsrichtlinie kann Ihr System negativ beeinflussen, falls hohe Parallelität, hohe Skalierbarkeit und ein hohes Konfliktpotenzial vorhanden sind. Um mit Spitzenlasten umgehen zu können, die bei ähnlichen Wiederholungsanforderungen von vielen Clients bei einem Teilausfall auftreten, empfiehlt es sich als Notlösung, den Wiederholungsalgorithmus oder die Wiederholungsrichtlinie um eine Jitterstrategie zu ergänzen. Diese Strategie kann die Gesamtleistung des End-to-End-Systems verbessern. Wie in Polly: Retry with Jitter empfohlen, lässt sich eine gute Jitterstrategie durch geglättete und gleichmäßig verteilte Wiederholungsintervalle implementieren, die mit einer gut kontrollierten anfänglichen Median-Wiederholungsverzögerung auf ein exponentielles Backoff angewendet werden. Dieser Ansatz hilft dabei, Spitzen zu verteilen, wenn das Problem auftritt. Das Prinzip wird im folgenden Beispiel dargestellt:


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

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

Zusätzliche Ressourcen