前言

在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
<https://github.com/fhcodegit/HttpClientFactoryPolly>
Polly:https://github.com/App-vNext/Polly <https://github.com/App-vNext/Polly>
参考:https://blog.csdn.net/qq_42606051/article/details/81698662
<https://blog.csdn.net/qq_42606051/article/details/81698662>