一、介绍
在IServiceCollection调用AddHttpClient注册IHttpClientFactory服务,调用AddHttpMessageHandler以生成出站请求中间件管道。 每个处理程序都可以在出站请求前后执行工作。通过Polly 的处理程序,以表达策略处理重试、断路器、超时、隔离和回退。
二、使用http请求
1.配置注册
var host = new HostBuilder() .ConfigureServices((context, services) => { services.AddHttpClient(); services.AddHostedService(); }) .UseConsoleLifetime() .Build();
2.请求的后台服务
public Task StartAsync(CancellationToken cancellationToken) { return Task.Run(async () => { var request = new HttpRequestMessage(HttpMethod.Post, "http://www.baidu.com"); request.Headers.Add("Accept", "application/json");//设置请求头 request.Properties.Add("id","123");//设置请求参数 var client = _clientFactory.CreateClient(); var response = await client.SendAsync(request); string result = null; if (response.IsSuccessStatusCode) { result = await response.Content.ReadAsStringAsync(); } }); }
3.执行时控制台输入日志
二、以客户端的方式使用
在客户端中配置,默认请求Url地址和默认的header。
public class HaosRequestService { public HttpClient Client { get; } public HaosRequestService(HttpClient client) { //配置默认值 client.BaseAddress = new Uri("http://www.baidu.com/"); client.DefaultRequestHeaders.Add("Accept","application/json"); Client = client; } ////// 封装常用方法 /// /// /// public async Task<string> SeachAsync(string key) { var content = new FormUrlEncodedContent(new[] { new KeyValuePair<string,string>("w","关键字"), }); var response = await Client.PostAsync("/s",content); response.EnsureSuccessStatusCode(); return await response.Content.ReadAsStringAsync(); } }
在IServiceCollection中注册
var host = new HostBuilder() .ConfigureServices((context, services) => { services.AddHttpClient(); services.AddHostedService (); })
三、处理出站 HTTP 请求
IHttpClientFactory 可以为客户端定义处理程,支持注册和链接多个处理程序。要创建处理程序,先定义一个继承 DelegatingHandler
的类。 重写 SendAsync
方法,在将请求传递至管道中的下一个处理程序之前
using System.Net.Http; using System.Threading; using System.Threading.Tasks; namespace Haos.Develop.HttpRequest.Samples { public class ColationDelegatingHandler:DelegatingHandler { protected override TaskSendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { //此处实现过滤逻辑 return base.SendAsync(request, cancellationToken); } } }
var Host = new HostBuilder() .ConfigureAppConfiguration(builder => { builder.AddCommandLine(args); }) .ConfigureServices((context, services) => { services.AddHttpClient() //注册过滤程序 .AddHttpMessageHandler (); }) .UseConsoleLifetime() .Build();
四、基于Polly的处理程序
Polly 以表达策略,例如以流畅且线程安全的方式处理重试、断路器、超时、Bulkhead 隔离和回退。Microsoft.Extensions.Http.Polly NuGet 包中提供 Polly 扩展实现将 Polly 策略用于配置的 HttpClient 实例。
Polly 添加策略分为三种
1. AddTransientHttpErrorPolicy:是处理Http请求的错误,如HTTP 5XX 的状态码,HTTP 408 的状态码 以及System.Net.Http.HttpRequestException异常
2. AddPolicyHandler:添加自定义策列
3. AddPolicyHandlerFromRegistry:从Policy注册表集合里面选择添加
a. AddTransientHttpErrorPolicy
.ConfigureServices((context, services) => { services.AddHttpClient() .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(3, t => TimeSpan.FromMilliseconds(500))) //或。上下都是定义了,错误重试上面是间隔都是500毫秒,下面则定义了每次重试的时间间隔 .AddTransientHttpErrorPolicy(builder => builder.WaitAndRetryAsync(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10) })); })
b. AddPolicyHandler
先定义策略,在通过AddPolicyHandler方法添加,改方法接收一个泛型的IAsyncPolicy
.ConfigureServices((context, services) => { var retryPolicy = Policy.Handle() .OrResult (response => { //此处实现处理改异常的逻辑 return true; }).WaitAndRetryAsync(3,t => TimeSpan.FromMilliseconds(50)); services.AddHttpClient () .AddPolicyHandler(retryPolicy); })
retryPolicy:发生HttpRequestException的异常,并且OrResult返回结果为true,采用这个策略
c. AddPolicyHandlerFromRegistry
先注册策略表服务,为策略表添加策略,最后通过AddPolicyHandlerFromRegistry方法选用某个或几个策略
.ConfigureServices((context, services) => { //注册,策略表服务 var registry = services.AddPolicyRegistry(); //创建策略 var retryPolicy = Policy.Handle() .OrResult (response => { //此处实现处理改异常的逻辑 return true; }).WaitAndRetryAsync(3, t => TimeSpan.FromMilliseconds(50)); registry.Add("registry1", retryPolicy); services.AddHttpClient () .AddPolicyHandlerFromRegistry("registry1"); })
添加多个 Polly 处理程序嵌套 Polly 策略以增强功
分别定义三种策略,timeoutPolicy,noOpPolicy,retryPolicy 通过策略表的方式和自定义。添加多个策略。
.ConfigureServices((context, services) => { //注册,策略表服务 var registry = services.AddPolicyRegistry(); //创建策略 var timeoutPolicy = Policy.TimeoutAsync(10);//10秒超时 var noOpPolicy = Policy.NoOpAsync().AsAsyncPolicy ();//有时我们也需要一个没有任何行为的策略,Polly系统默认提供了一个. var retryPolicy = Policy.Handle () .OrResult (response => { //此处实现处理改异常的逻辑 return true; }).WaitAndRetryAsync(3, t => TimeSpan.FromMilliseconds(50)); registry.Add("registry1", retryPolicy); registry.Add("registry2", timeoutPolicy); services.AddHttpClient () .AddPolicyHandlerFromRegistry("registry1") .AddPolicyHandler(retryPolicy) .AddPolicyHandler(timeoutPolicy); })