在 .NET Core 中結合 HttpClientFactory 使用 Polly(上篇)
譯者:王亮
作者:Polly 團隊
原文:http://t.cn/EhZ90oq
譯者序一:前兩天寫了一篇文章 .NET Core 開源專案 Polly 介紹,在寫這篇文章檢視 Polly 資料時,看到了“Polly and HttpClientFactory”這篇 Wiki 文件,覺得很有價值,於是抽時間把它翻譯了一下,並和大家分享。由於翻譯下來篇幅過長,所以我分成了上、中、下三篇,這是上篇。
譯者序二:如果你對 ASP.NET Core 2.1 新引入的 HttpClient 工廠還比較陌生,建議先閱讀我的另一篇文章 .NET Core 中正確使用 HttpClient 的姿勢
譯者序三:特別宣告一下,我翻譯技術文章不是逐句翻譯的,而是根據我自己的理解來表述的(包括標題)。其中可能會去除一些不影響理解但本人實在不知道如何組織的句子。
· 正 · 文 · 來 · 啦 ·
ASPNET Core 2.1 的 HttpClient 工廠允許預配置 HttpClient 例項,這樣我們可以對 HttpClient 例項預配置 Polly 策略,將它應用到每次向外的網路請求中。
什麼是 HttpClient 工廠
從 ASPNET Core 2.1 開始, Polly 集成了 IHttpClientFactory。HttpClient 工廠從以下四個方面簡化了 HttpClient 的管理和使用:
-
允許你用命名的方式來配置和使用 HttpClint。例如,您可以預先配置和命名一個訪問 GitHub API 的客戶端。
-
管理 HttpClientMessageHandler 的生命週期,以避免與你自己來管理 HttpClient 的痛苦(可能會遇到一些嚴重的問題,具體請看 http://t.cn/EhZ8Bxw 和 http://t.cn/EhZRw53)。
-
可以為工廠建立的 Client 的所有請求和響應提供可配置的日誌(通過 ILogger)。
-
提供了一個簡單的 API,用於向外請求新增中介軟體,包括日誌、授權、服務發現或 Polly 的彈性策略。
Steve Gordon 在他的部落格寫了四篇系列文章介紹了 HttpClient 工廠的使用並給出了很好的例子。另外官方也有 HttpClient 工廠的文件。
IHttpClientFactory 和 Polly 結合使用
第一步:新增專案引入
從 NuGet 獲取 ASPNET Core 2.1 相關的包,通常需要需要 AspNetCore 元包(不需要手動新增,模板預設新增好了)和 Microsoft.Extensions.Http.Polly 擴充套件包。
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.1</TargetFramework> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.App" Version="2.1.0" /> <PackageReference Include="Microsoft.Extensions.Http.Polly" Version="2.1.0" /> </ItemGroup></Project>
注意:當您閱讀本文時,這些包可能已經有了更高的版本。
第二步: 在 Startup 中 配置 Polly 策略
在你的 Startup.ConfigureServices 方法中配置一個命名的 HttpClient,如下:
public void ConfigureServices(IServiceCollection services){ services.AddHttpClient("GitHub", client => { client.BaseAddress = new Uri("https://api.github.com/"); client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json"); }); // ...}
這裡我們寫死了配置字串,實際專案中應該從配置檔案中獲取。
我們將重點討論如何使用 Polly 策略來配置它,但是配置命名的 HttpClient 還有很多選項,你可以從官方的文件或 Steve Gordon 和 Scott Hanselman 的部落格中瞭解這些選項。根據你的喜好,也可以使用型別化的 HttpClient。
為了使用 Polly 策略,你只需要在上面的示例中擴充套件一下:
services.AddHttpClient("GitHub", client =>{ client.BaseAddress = new Uri("https://api.github.com/"); client.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");}).AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[]{ TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10)}));
這個示例建立了一個策略,該策略將處理典型的瞬態故障,如果需要,會最多重試 3 次 Http 請求。這個策略將在第一次重試前延遲 1 秒,第二次重試前 5 秒,在第三次重試前延遲 10 秒。
AddTransientHttpErrorPolicy 的過載方法有許多選項,我們將在介紹完基礎知識之後再來檢視這些選項。
第三步:消費配置好的 HttpClient
為了完整上面的示例,下面是一個使用配置好的 HttpClient 示例。對於命名 HttpClient(如上例所示),在 Controller 中通過依賴注入獲取一個 IHttpClientFactory,然後用它獲得配置好的 HttpClient:
public class MyController : Controller{ private readonly IHttpClientFactory _httpClientFactory; public MyController(IHttpClientFactory httpClientFactory) { _httpClientFactory = httpClientFactory; } public Task<IActionResult> SomeAction() { var client = _httpClientFactory.CreateClient("GitHub"); return Ok(await client.GetStringAsync("/someapi")); }}
再提一下, Steve Gordon 和 Scott Hanselman 的部落格有更豐富的例子, 包括型別化的方式使用 HttClient。
Polly 策略是如何被應用的
你配置到 HttpClient 上的 Polly 策略會被應用到一個基於 Polly 的 DelegatingHandler 的向外呼叫上。這意味著策略將應用於通過配置的 HttpClient 的所有向外呼叫。
如果您過去嘗試手動重試 HttpClient.DoSomethingAsync 的向外呼叫,您可能會發現 HttpRequestMessage 在傳送後不能重用(這樣做會引發 InvalidOperationException 異常),DelegatingHandler 的方式則避免了這個問題。
DelegatingHandler 只是用於向外 HTTP 呼叫的中介軟體,請參閱 Steve Gordon 部落格的文章 (連結:http://t.cn/Ehwz16W) 瞭解 DelegatingHandler 如何工作。
相關文章: