使用指數退避的重試建議方法是利用更進階的 .NET 程式庫,例如開放原始碼的 Polly 程式庫。
Polly 是 .NET 連結庫,可提供復原和暫時性錯誤處理功能。 您可以透過套用 Polly 的策略來實作這些功能,例如重試、斷路器、隔艙隔離、逾時和後備。 Polly 以 .NET Framework 4.x 和 .NET Standard 1.0、1.1 和 2.0 為目標(支援 .NET Core 和更新版本)。
下列步驟說明如何使用 Http 重試搭配整合至 IHttpClientFactory
的 Polly,如上一節所述。
安裝 .NET 套件
首先,您必須安裝 Microsoft.Extensions.Http.Polly
套件。
參考 .NET 8 套件
IHttpClientFactory
從 .NET Core 2.1 開始便可用,但我們建議您在專案中使用來自 NuGet 的最新 .NET 8 套件。 您通常也需要參考延伸模組套件 Microsoft.Extensions.Http.Polly
。
在應用程式啟動時,使用 Polly 的重試原則設定用戶端
AddPolicyHandler() 方法是將原則新增至HttpClient
您將使用的物件。 在此情況下,這是為 HTTP 重試加入一個含有指數退避的 Polly 策略。
若要有更模組化的方法,Http 重試原則可以在 Program.cs 檔案內的個別方法中定義,如下列程式代碼所示:
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 例外 狀況時要採取的動作,例如記錄錯誤。 在此情況下,原則設定為使用指數重試嘗試六次,從兩秒開始。
將抖動策略添加至重試策略
常規重試策略可能會在高並行性及延展性要求,及高爭用的情況下影響您的系統。 若要克服來自部分中斷中許多客戶端的類似重試尖峰,良好的因應措施是將抖動策略新增至重試演算法/原則。 此策略可以改善端對端系統的整體效能。 如 Polly:使用抖動重試所建議,可透過平順且均勻分佈的重試間隔來實行有效的抖動策略,並在指數退避中套用控制良好的中位數初始重試延遲。 此方法有助於在問題發生時分散負荷高峰。 下列範例說明此原則:
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:使用抖動重試https://github.com/App-vNext/Polly/wiki/Retry-with-jitter
馬克·布魯克 抖動:使用隨機性讓事情變得更好 https://brooker.co.za/blog/2015/03/21/backoff.html