HttpClient 與 Polly 進行重試與斷路策略 - Microsoft.Extensions.Http.Resilience
HttpClient 與 Polly 進行重試與斷路策略 - Microsoft.Extensions.Http.Resilience
在開發WebAPI串接第三方服務或是其他服務,通常會在HttpClient連線部分進行設定 Polly,以前會使用 Microsoft.Extensions.Http.Polly套件,但是最近翻文件發現 Polly 更新版本提供了 Pipeline 使用方式。
使用 HttpClientFactory 微軟官方也有新增 Microsoft.Extensions.Http.Resilience 來支援這方式。比起 Policy 方式宣告 Pipeline 在效能上更優化。而且提供斷路器可以進行監控狀態及手動控制等功能,讓斷路器實作上更方便。下面範例使用 .Net 8 進行示範。
Polly 官方文件
微軟官方文件
https://learn.microsoft.com/en-us/dotnet/core/resilience/?tabs=dotnet-cli
安裝方式
1 | dotnet add package Microsoft.Extensions.Http.Resilience |
Circuit Breaker 斷路器實作與設定
比起之前版本新版提供 CircuitBreakerStateProvider、CircuitBreakerManualControl類別。但是需要依照各斷路器設定不同的狀態提供者及控制器。
CircuitBreakerManualControl.cs 介紹
提供兩個方法 CloseAsync、IsolateAsync進行手動控制斷路器。
IsolateAsync(隔離)
IsolateAsync 方法將斷路器手動設置為 Isolated 狀態。當呼叫此方法後,斷路器將進入隔離狀態,阻止所有請求的執行,無論系統是否正常。此狀態會保持,直到手動解除隔離。CloseAsync(關閉)
CloseAsync 方法將斷路器手動恢復到 Closed 狀態,允許所有請求正常通過。
CircuitBreakerStateProvider.cs 介紹
CircuitBreakerStateProvider.cs 有提供目前狀態 CircuitState ,並裡面有四種狀態以下是這四種狀態介紹。
Closed(關閉狀態):
在 Closed 狀態下,斷路器允許執行所有操作。這表示電路正常運作,所有請求都會通過。通常當操作成功率高且錯誤次數未達到設定的閾值時,斷路器會保持在 Closed 狀態。Open(開啟狀態):
Open 狀態通常由控制器觸發,表示斷路器已被打開。這是因為請求失敗次數超過了設定閥值。在 Open 狀態下,所有操作的執行會被阻止,並拋出BrokenCircuitException。Half-open(半開狀態):
Half-open 狀態表示斷路器正在從 Open 狀態恢復。當斷路器經過設定的 BreakDuration 時間後進入此狀態,表示正在嘗試恢復正常的請求處理。在此狀態下,斷路器會允許部分請求通過並監控其結果。如果這些請求成功,斷路器改到 Closed 狀態;如果請求再次失敗,斷路器回到 Open 狀態。Isolated(隔離狀態):
Isolated 狀態表示斷路器被手動隔離進入 Open 狀態。這是透過呼叫CircuitBreakerManualControl.IsolateAsync方法。在此狀態下,所有操作的執行會被阻止,並拋出 IsolatedCircuitException ,直到手動呼叫CircuitBreakerManualControl.CloseAsync方法將斷路器改為 Closed 狀態。
設定
這邊在設定上說明一下每欄位
Polly 官方文件
FailureRatio為失敗率必須是0~1。如果是0.1的話,表示發送請求中達到10%的失敗就進行斷路。SamplingDuration計算失敗-成功比率的時間段。MinimumThroughput在指定的採樣持續時間內必須發生的最小執行次數。BreakDuration斷路時間長度,等到時間結束並不會馬上恢復,而是進行少量的請求。確定了服務正常才進行打開。StateProvider如果提供,則可以透過物件檢索電路的當前狀態。ManualControl如果提供,則可以透過物件手動控制電路的狀態。
Program.cs
1 |
|
使用方式
只需要與之前使用HttpClientFactory方式一樣即可
1 |
|
演示範例
這邊也提供範例程式碼,為了測試方便範例程式碼只需要1分鐘內執行兩次回應為Ok(ShouldHandle 設定為 response.StatusCode 200 )以上就會觸發斷路器的 Closed,做一個簡單畫面進行觀察。
- 原本正常不啟動斷路

- 進行觸發斷路系統會拋出
BrokenCircuitException

- 查詢斷路狀態為 Open

- 恢復成手動點擊關閉斷路或是等待
BreakDuration時間過去

- 手動點擊斷路器,則狀態變更為 Isolated

- 在狀態為 Isolated,發送請求系統會拋出
IsolatedCircuitException

範例程式碼
關於上面的程式碼也提供在個人Github上面有完整的範例程式碼
- 範例專案 PollySample
