這篇文章要分享我最近在研究 Microsoft.Extensions.Http.Resilience 與 Microsoft.Extensions.Http.Polly 的心得,特別是 Retry 策略 的使用方式與效能比較。
在 .NET 8 之後,微軟官方推出了新的 Resilience Handler,它內建在 Microsoft.Extensions.Http.Resilience 套件中,不再需要額外安裝 Polly 套件就能使用 Retry、Circuit Breaker、Timeout 等彈性策略。
開發環境
- Windows 11 Pro / Ubuntu 24.04 (WSL2)
- .NET 9.0.4
- BenchmarkDotNet v0.15.4
套件依賴
Microsoft.Extensions.Http.Polly 套件依賴關係

Microsoft.Extensions.Http (9.0.9)
- HTTP 用戶端基礎設施
- 提供 HttpClientFactory 支援
- 整合 .NET 的 HTTP 用戶端管理
Microsoft.Extensions.DependencyInjection (9.0.9)
- 依賴注入容器
- 服務註冊和解析
Polly (7.2.4)
- 彈性和故障處理庫
- 提供重試、斷路器、逾時等彈性模式
Microsoft.Extensions.Http.Resilience 套件依賴關係

Microsoft.Extensions.Http (9.0.9)
- HTTP 用戶端基礎設施
- 提供 HttpClientFactory 支援
- 依賴於 DI、Logging、Options 框架
Microsoft.Extensions.Resilience (9.9.0)
- 彈性模式核心功能
- 整合 Polly.Core 和 Polly.Extensions
- 提供遙測和合規性抽象化
Polly.Extensions.Http (3.0.0)
- Polly 的 HTTP 專用擴充功能
- 依賴 Polly.Core 和傳統 Polly 套件
- 支援限流功能
Polly.Core (8.4.2)
- Polly 的新一代核心引擎
- 支援 System.Threading.RateLimiting
Microsoft.Extensions.Http.Resilience 使用方式
Resilience 套件提供了 標準化的彈性處理器,只要一行 .AddStandardResilienceHandler() 就能套用官方建議的 Retry、Timeout、Circuit Breaker 策略。
services.AddHttpClient("resilience", client => { client.BaseAddress = new Uri("http://localhost:5068"); })
.AddStandardResilienceHandler();
如果要自訂 Retry 策略,可以用 AddResilienceHandler:
services.AddHttpClient("pollyV8", client => { client.BaseAddress = new Uri("http://localhost:5068"); })
.AddResilienceHandler("retry", builder =>
{
builder.AddRetry(new RetryStrategyOptions<HttpResponseMessage>
{
MaxRetryAttempts = 3,
BackoffType = DelayBackoffType.Exponential,
Delay = TimeSpan.FromSeconds(1),
ShouldHandle = new PredicateBuilder<HttpResponseMessage>()
.HandleResult(response => !response.IsSuccessStatusCode)
.Handle<HttpRequestException>()
});
});
這裡的 API 設計和 Polly V8 幾乎一樣,因為 Resilience Handler 本身就是基於 Polly V8 的 Resilience Pipeline。
Microsoft.Extensions.Http.Polly 使用方式
在 Resilience Handler 出現之前,我們都是透過 Microsoft.Extensions.Http.Polly 來整合 Polly 策略。
以下是最常見的 Retry 寫法:
// 設定 Polly V7 客戶端 (傳統方式,使用 Microsoft.Extensions.Http.Polly)
services.AddHttpClient("pollyV7", client => { client.BaseAddress = new Uri(_baseUrl); })
.AddPolicyHandler(GetRetryPolicyV7());
這種寫法依賴 Polly V7 的 API,屬於舊式的 Policy Chain。
如果升級到 Polly V8,則可以改用 Resilience Pipeline 的方式,語法就會和 Microsoft.Extensions.Http.Resilience 幾乎一致。
效能比較:Polly vs Resilience
我用 BenchmarkDotNet 做了壓測,結果如下(詳細數據來自 [FIXED_BENCHMARK_RESULTS.md] 與 [POLLY_V8_介紹.md]):
方法 | 平均時間 | 標準差 | 記憶體分配 |
---|---|---|---|
StandardHttpClient | 158.0 μs | 6.68 μs | 3.31 KB |
Polly V8 | 171.9 μs | 8.32 μs | 4.95 KB |
Resilience | 174.7 μs | 8.46 μs | 6.48 KB |
Polly V7 | 204.3 μs | 33.64 μs | 4.46 KB |
關鍵觀察
- Polly V8 比 Polly V7 快了 15.9%,而且穩定性大幅提升(標準差降低 75%)。
- Resilience Handler 的效能和 Polly V8 幾乎一樣,差異僅 2.8%,但記憶體使用稍高。
心得
- 如果你是 新專案,建議直接用 Microsoft.Extensions.Http.Resilience,因為它是官方推薦、長期維護的方案。
- 如果你已經在用 Polly V8,其實和 Resilience 幾乎一樣,差別只在於整合度。
- 如果還在用 Polly V7,強烈建議規劃遷移,因為效能與穩定性都落後太多。
範例位置
若有謬誤,煩請告知,新手發帖請多包涵
Microsoft MVP Award 2010~2017 C# 第四季
Microsoft MVP Award 2018~2022 .NET