使用 IHttpClientFactory 和 Polly 原則以指數輪詢實作 HTTP 呼叫重試
提示
本內容節錄自《容器化 .NET 應用程式的 .NET 微服務架構》(.NET Microservices Architecture for Containerized .NET Applications) 電子書,可以在 .NET Docs 上取得,或免費下載可供離線閱讀的 PDF。
使用指數輪詢重試的建議方法是利用更進階的 .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 套件
首先,您需要安裝 Microsoft.Extensions.Http.Polly
套件。
參考 .NET 8 套件
自 .NET Core 2.1 後提供 IHttpClientFactory
,不過,建議您在專案中使用 NuGet 中的最新 .NET 8 套件。 您通常也需要參考延伸模組套件 Microsoft.Extensions.Http.Polly
。
在應用程式啟動時,使用 Polly 的重試原則來設定用戶端
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)));
}
如前幾節所示,您必須在標準 Program.cs 應用程式組態中定義具名或具類型的用戶端 HttpClient 設定。 現在,您可以新增累加程式碼,以使用指數輪詢來指定 HTTP 重試的原則,如下所示:
// Program.cs
builder.Services.AddHttpClient<IBasketService, BasketService>()
.SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Set lifetime to five minutes
.AddPolicyHandler(GetRetryPolicy());
透過 Polly,您可以定義重試原則,其中包含重試次數、指數輪詢組態,以及發生 HTTP 例外狀況時所要採取的動作,例如記錄錯誤。 在本例中,會設定原則,以便使用指數重試嘗試六次,一開始每隔兩秒。
將 Jitter 策略新增至重試原則
如果發生高並行和高可擴縮性以及高競爭的情況,則定期重試原則可能會影響您的系統。 若要解決在部分中斷時來自許多用戶端的類似重試達到最高的問題,一個很好的解決方法是將 Jitter 策略新增至重試演算法/原則。 此策略可改善端對端系統的整體效能。 如 Polly:使用 Jitter 重試 (英文) 所建議,可透過順暢且平均分配的重試間隔,並在指數輪詢上套用妥善控制的中位數初始重試延遲,來實作良好的 Jitter 策略。 此方法有助於在問題發生時分散峰值。 下列=範例會說明這個準則:
var delay = Backoff.DecorrelatedJitterBackoffV2(medianFirstRetryDelay: TimeSpan.FromSeconds(1), retryCount: 5);
var retryPolicy = Policy
.Handle<FooException>()
.WaitAndRetryAsync(delay);
其他資源
重試模式https://learn.microsoft.com/azure/architecture/patterns/retry
Polly 和 IHttpClientFactoryhttps://github.com/App-vNext/Polly/wiki/Polly-and-HttpClientFactory
Polly (.NET 復原和暫時性錯誤處理程式庫)https://github.com/App-vNext/Polly
Polly:使用 Jitter 重試https://github.com/App-vNext/Polly/wiki/Retry-with-jitter
Marc Brooker: Jitter: Making Things Better With Randomness (Jitter:利用隨機性更臻完美) https://brooker.co.za/blog/2015/03/21/backoff.html