Microsoft.Extensions.Http.Resilience 效能比較

這篇文章要分享我最近在研究 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]):

方法平均時間標準差記憶體分配
StandardHttpClient158.0 μs6.68 μs3.31 KB
Polly V8171.9 μs8.32 μs4.95 KB
Resilience174.7 μs8.46 μs6.48 KB
Polly V7204.3 μs33.64 μs4.46 KB

關鍵觀察

  1. Polly V8 比 Polly V7 快了 15.9%,而且穩定性大幅提升(標準差降低 75%)。
  2. 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

Image result for microsoft+mvp+logo