前言 在 NET Core2.1 後也是增加更新了很多東西,當然 HttpClientFactory 更新中的一部分.雖然說 HttpClient 這個實現了 disposable ,但使用它的時候用using包裝塊的方式通常不是最好的選擇。處理 HttpClient ,底層 socket 套接字不 ...
前言
在NET Core2.1後也是增加更新了很多東西,當然HttpClientFactory更新中的一部分.雖然說HttpClient這個實現了disposable,但使用它的時候用using包裝塊的方式通常不是最好的選擇。處理HttpClient,底層socket套接字不會立即釋放。該HttpClient類是未多個請求重覆使用而創建的。需要不同的基地址,不同的HTTP 標頭和其他對請求個性化操作的場景時,需要動手管理多個HttpClient實例,為了簡化HttpClient實例管理,.NET Core 2.1提供了一個新的HTTPClientFactory - 它可以創建,緩存和處理HttpClient實例。
什麼是HttpClientFactory
從ASPNET Core開始,Polly與IHttpClientFastory集成。HttpClientFastory是一個簡化管理和使用的HttpClientory。用ASP.Net團隊的話說:“an opinionated factory for creating HttpClient instances”(一個用於創建HttpClient實例的最佳實踐的工廠)
- 提供命名和配置邏輯HttpClient 對象的中心位置。例如,您可以配置預先配置為訪問特定微服務的客戶端(服務代理)。
- 通過委派處理程式HttpClient 並實施基於Polly 的中間件來利用Polly 的彈性策略,對傳出中間件的概念進行編碼。
- HttpClient 已經有了委托處理程式的概念,這些處理程式可以鏈接在一起用於傳出HTTP 請求。您將HTTP 客戶端註冊到工廠中,並且可以使用Polly處理程式將Polly策略用於Retry,CircuitBreakers 等。
- 管理生命周期,HttpClientMessageHandlers 以避免在管理HttpClient 自己的生命周期時可能發生的上述問題/問題。
HttpClientFactory簡單使用
- Startup添加
services.AddHttpClient();
- 通過IHttpClientFactory創建一個HttpClient對象,後面操作如舊,但是不需要關心其資源釋放
using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Threading.Tasks;
namespace HttpClientFactoryPolly.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
private readonly IHttpClientFactory _httpClientFactory;
public ValuesController(IHttpClientFactory httpClientFactory)
{
this._httpClientFactory = httpClientFactory;
}
// GET api/values
[HttpGet]
public async Task<ActionResult<string>> Get()
{
var client = _httpClientFactory.CreateClient();
var result =await client.GetStringAsync("https://www.microsoft.com/zh-cn/");
return result;
}
}
}
配置HttpClientFactory Polly
這邊採用命名客戶端演示該慄子(如果應用需要有許多不同的 HttpClient 用法(每種用法的配置都不同),可以視情況使用命名客戶端。 可以在 HttpClient 中註冊時指定命名 Startup.ConfigureServices 的配置。)
- Package
PM> Install-package Microsoft.Extensions.Http.Polly
Startup
services.AddHttpClient("github",c=> {
//基址
c.BaseAddress = new System.Uri("https://api.github.com/");
// Github API versioning
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
});
[HttpGet("{id}")]
public async Task<ActionResult<string>> Get(int id)
{
var request = new HttpRequestMessage(HttpMethod.Get,
"repos/aspnet/docs/pulls");
var client = _httpClientFactory.CreateClient("github");
var response = await client.SendAsync(request);
var result =await response.Content.ReadAsStringAsync();
return result;
}
- 重試機制
services.AddHttpClient("github", c =>
{
//基址
c.BaseAddress = new System.Uri("https://api.github.com/");
// Github API versioning
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
//AddTransientHttpErrorPolicy主要是處理Http請求的錯誤,如HTTP 5XX 的狀態碼,HTTP 408 的狀態碼 以及System.Net.Http.HttpRequestException異常
}).AddTransientHttpErrorPolicy(p =>
//WaitAndRetryAsync參數的意思是:每次重試時等待的睡眠持續時間。
p.WaitAndRetryAsync(3, _ => TimeSpan.FromMilliseconds(600)));
效果如下
- 熔斷降級超時
services.AddHttpClient("test", c =>
{
//基址
c.BaseAddress = new System.Uri("http://localhost:5000/");
// Github API versioning
c.DefaultRequestHeaders.Add("Accept", "application/vnd.github.v3+json");
// Github requires a user-agent
c.DefaultRequestHeaders.Add("User-Agent", "HttpClientFactory-Sample");
})
// 降級
.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().FallbackAsync(fallbackResponse, async b =>
{
Console.WriteLine($"fallback here {b.Exception.Message}");
}))
// 熔斷
.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().CircuitBreakerAsync(2, TimeSpan.FromSeconds(4), (ex, ts) =>
{
Console.WriteLine($"break here {ts.TotalMilliseconds}");
}, () =>
{
Console.WriteLine($"reset here ");
}))
// 超時
.AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(1));
}
設置降級策略當出現任何異常返回fallback
設置熔斷策略當連續出現異常異常 2 次,熔斷 4s;
設置超時策略,請求超時為 1s,超時預設會拋出 TimeoutRejectedException;
效果如下
概要
示例地址:https://github.com/fhcodegit/HttpClientFactoryPolly
Polly:https://github.com/App-vNext/Polly
參考:https://blog.csdn.net/qq_42606051/article/details/81698662