使用 IHttpClientFactory 和 Polly 原則以指數輪詢實作 HTTP 呼叫重試

提示

此內容是適用于容器化 .NET 應用程式的電子書、.NET 微服務架構的摘錄,可在 .NET Docs 上取得,或作為可離線讀取的免費可下載 PDF。

容器化 .NET 應用程式電子書的 .NET 微服務架構涵蓋縮圖。

使用指數輪詢重試的建議方法是利用更進階的 .NET 程式庫,例如開放原始碼 Polly 程式庫

Polly 是 .NET 程式庫,提供恢復功能和暫時性錯誤處理功能。 您可以藉由套用重試、斷路器、艙壁隔離 (Bulkhead Isolation)、逾時和後援等 Polly 原則,來實作這些功能。 Polly 目標.NET Framework 4.x 和 .NET Standard 1.0、1.1 和 2.0 (,其支援 .NET Core 和更新版本) 。

下列步驟示範如何透過整合到 IHttpClientFactory 中的 Polly 使用 HTTP 重試,如上一節所述。

參考 .NET 7 套件

IHttpClientFactory 自 .NET Core 2.1 起提供,不過,建議您在專案中使用來自 NuGet 的最新 .NET 7 套件。 您通常也需要參考延伸模組套件 Microsoft.Extensions.Http.Polly

在應用程式啟動時,使用 Polly 的重試原則來設定用戶端

如前幾節所示,您必須在標準 Program.cs 應用程式組態中定義具名或具類型的用戶端 HttpClient 設定。 現在,您會新增累加程式碼,以使用指數輪詢來指定 Http 重試的原則,如下所示:

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

AddPolicyHandler() 方法會將原則新增至您將使用的 HttpClient 物件。 在此案例中,它會為使用指數輪詢的 HTTP 重試新增 Polly 原則。

為了有更模組化的方法,可在 Program.cs 檔案內的個別方法中定義 Http 重試原則,如下列程式碼所示:

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

透過 Polly,您可以定義重試原則,其中包含重試次數、指數輪詢組態,以及發生 HTTP 例外狀況時所要採取的動作,例如記錄錯誤。 在本例中,會設定原則,以便使用指數重試嘗試六次,一開始每隔兩秒。

將 Jitter 策略新增至重試原則

如果發生高並行和高可擴縮性以及高競爭的情況,則定期重試原則可能會影響您的系統。 若要解決在部分中斷時來自許多用戶端的類似重試達到最高的問題,一個很好的解決方法是將 Jitter 策略新增至重試演算法/原則。 此策略可改善端對端系統的整體效能。 如 Polly:使用 Jitter 重試 (英文) 所建議,可透過順暢且平均分配的重試間隔,並在指數輪詢上套用妥善控制的中位數初始重試延遲,來實作良好的 Jitter 策略。 此方法有助於在問題發生時分散峰值。 下列=範例會說明這個準則:


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

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

其他資源