zoukankan      html  css  js  c++  java
  • .Net Core 使用Http请求及基于 Polly 的处理故障

    一、介绍

      在IServiceCollection调用AddHttpClient注册IHttpClientFactory服务,调用AddHttpMessageHandler以生成出站请求中间件管道。 每个处理程序都可以在出站请求前后执行工作。通过Polly 的处理程序,以表达策略处理重试、断路器、超时、隔离和回退。

    二、使用http请求

    1.配置注册

    var host = new HostBuilder()
          .ConfigureServices((context, services) => {
                services.AddHttpClient();
                services.AddHostedService<MyHostedService>();
          })
          .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;
            }
            /// <summary>
            /// 封装常用方法
            /// </summary>
            /// <param name="key"></param>
            /// <returns></returns>
            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<HaosRequestService>();
                        services.AddHostedService<MyHostedService>();
                    })

    三、处理出站 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 Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                //此处实现过滤逻辑
                return base.SendAsync(request, cancellationToken);
            }
        }
    }
    var Host = new HostBuilder()
        .ConfigureAppConfiguration(builder =>
        {
            builder.AddCommandLine(args);
        })
        .ConfigureServices((context, services) =>
        {
            services.AddHttpClient<RequestClient>()
            //注册过滤程序
            .AddHttpMessageHandler<ColationDelegatingHandler>();
        })
        .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<RequestClient>()
        .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<HttpResponseMessage>。HttpResponseMessage我理解为出站请求上下文

    .ConfigureServices((context, services) =>
    {
        var retryPolicy = Policy.Handle<HttpRequestException>()
        .OrResult<HttpResponseMessage>(response => {
            //此处实现处理改异常的逻辑
            return true;
        }).WaitAndRetryAsync(3,t => TimeSpan.FromMilliseconds(50));
    
        services.AddHttpClient<RequestClient>()
        .AddPolicyHandler(retryPolicy);
    })
    retryPolicy:发生HttpRequestException的异常,并且OrResult返回结果为true,采用这个策略

      c. AddPolicyHandlerFromRegistry

      先注册策略表服务,为策略表添加策略,最后通过AddPolicyHandlerFromRegistry方法选用某个或几个策略

    .ConfigureServices((context, services) =>
    {
        //注册,策略表服务
        var registry = services.AddPolicyRegistry();
        //创建策略
        var retryPolicy = Policy.Handle<HttpRequestException>()
        .OrResult<HttpResponseMessage>(response => {
            //此处实现处理改异常的逻辑
            return true;
        }).WaitAndRetryAsync(3, t => TimeSpan.FromMilliseconds(50));
        registry.Add("registry1", retryPolicy);
        services.AddHttpClient<RequestClient>()
        .AddPolicyHandlerFromRegistry("registry1");
    })

      添加多个 Polly 处理程序嵌套 Polly 策略以增强功

        分别定义三种策略,timeoutPolicy,noOpPolicy,retryPolicy 通过策略表的方式和自定义。添加多个策略。

    .ConfigureServices((context, services) =>
    {
        //注册,策略表服务
        var registry = services.AddPolicyRegistry();
        //创建策略
        var timeoutPolicy = Policy.TimeoutAsync<HttpResponseMessage>(10);//10秒超时
        var noOpPolicy = Policy.NoOpAsync().AsAsyncPolicy<HttpResponseMessage>();//有时我们也需要一个没有任何行为的策略,Polly系统默认提供了一个.
        var retryPolicy = Policy.Handle<HttpRequestException>()
        .OrResult<HttpResponseMessage>(response => {
            //此处实现处理改异常的逻辑
            return true;
        }).WaitAndRetryAsync(3, t => TimeSpan.FromMilliseconds(50));
        registry.Add("registry1", retryPolicy);
        registry.Add("registry2", timeoutPolicy);
        services.AddHttpClient<RequestClient>()
        .AddPolicyHandlerFromRegistry("registry1")
        .AddPolicyHandler(retryPolicy)
        .AddPolicyHandler(timeoutPolicy);
    })
  • 相关阅读:
    GIL锁、进程池和线程池、同步和异步
    线程
    socket编程
    单例模式
    反射、自定义内置方法来定制类的功能、元类
    elasticSearch(一)--数据1
    docker学习整理(三)
    docker学习整理(二)
    docker学习整理(一)
    IDEA 配置mybatis生成代码
  • 原文地址:https://www.cnblogs.com/haosit/p/9722213.html
Copyright © 2011-2022 走看看