zoukankan      html  css  js  c++  java
  • Polly失败重试

    使用组件包
    Polly
    Polly.Extensions.Http
    Microsoft.Extensions.Http.Polly
    Polly策略功能

    1、失败重试

    调用失败的时候,重新尝试操作

    方法:retry(重试次数,一直重试,等待事件后重试)

    2、服务熔断

    部分服务不可用的时候,应用可以快速响应一个熔断的结果,这样熔断的应用就不会一直被请求。从而不会是不可用服务一直被请求从而是整个应用服务崩溃。

    方法:CircuitBreaker

     发生10以异常,熔断10秒钟

                services.AddHttpClient("orderclientv3").AddPolicyHandler(Policy<HttpResponseMessage>.Handle<HttpRequestException>().CircuitBreakerAsync(
                    handledEventsAllowedBeforeBreaking: 10,
                    durationOfBreak: TimeSpan.FromSeconds(10),
                    onBreak: (r, t) => { },
                    onReset: () => { },
                    onHalfOpen: () => { }
                    ));

    高级用法,跟进失败比例。  80%出错就熔断, 第二个参数  多长时间内出现80%错误,第三个参数  当请求比较少时候,最少的请求数,下面就是  10秒内 请求小于100个就还不需要熔断。第四个参数 熔断时间长度

                services.AddHttpClient("orderclientv3").AddPolicyHandler(Policy<HttpResponseMessage>.Handle<HttpRequestException>().AdvancedCircuitBreakerAsync(
                    failureThreshold: 0.8,
                    samplingDuration: TimeSpan.FromSeconds(10),
                    minimumThroughput: 100,
                    durationOfBreak: TimeSpan.FromSeconds(20),
                    onBreak: (r, t) => { },
                    onReset: () => { },
                    onHalfOpen: () => { }));

    应用程序熔断的时候会抛出一个异常  BrokenCircuitException。这个异常可以让后续策略使用。比如说  熔断后  在降级

    3、超时处理

    我们给服务设置一个超时时间,如果超过时间。就按照我们设定的返回,比如说一个缓存的结果。

    方法:Timeout

     

    4、舱壁隔离

    实际上是一个限流的功能,为服务定义最大的流量和队列,控制请求量过大而被压崩。

    方法:Bulkhead

    限流抛出异常  BulkheadRejectedException,可以供后续策略使用

    5、缓存策略

    类似于AOP的机制为应用嵌入缓存。当缓存命中快速响应换存,而不是每次都请求服务。

    方法:Cache

    6、失败降级  也叫  回退

    当我的服务不可用的时候,我们响应一个更加友好的结果,而不是报错。

    方法:FallBack

    7、组合策略

    可以将上面的策略组合在一起

    我们将超时策略(Timeout)加上回退(FallBack)策略组合使用

    Polly使用步骤
    • 定义要处理的异常类型或返回值
    • 定义要处理动作(重试、熔断、降级响应等)
    • 使用定义的策略来执行代码
    失败重试场景
    1、服务失败是暂时的,可以自愈的。
    比如说网络闪断
    服务的部分结点不可用
    2、服务是幂等的,重复调用不会有副作用
    最佳实践
    1、设置失败重试次数
    2、设置带有步长策略的失败等待时间
    3、设置降级响应
    重试次数达到某个值,就应该让服务降级
    4、设置断路器
    重试很多次还是不可用,就要短路了。这就是熔断
    HttpClient
                services.AddGrpcClient<OrderGrpc.OrderGrpcClient>(options =>
                {
                    options.Address = new Uri("https://localhost:5001");
                }).ConfigurePrimaryHttpMessageHandler(provider =>
                {
                    var handler = new SocketsHttpHandler();
                    handler.SslOptions.RemoteCertificateValidationCallback = (a, b, c, d) => true; //允许无效、或自签名证书
                    return handler;
                }).AddTransientHttpErrorPolicy(t => t.RetryAsync(3));
                //1、对HttpRequestException 500 408这样的错误会执行
    
                #region 2、策略
                #region 定义策略
                //服务中注册策略
                var reg= services.AddPolicyRegistry();
                //捕捉到异常HttpResponseMessage 且  响应码是BadRequest ,重试3次 
                reg.Add("Retry3", Policy.HandleResult<HttpResponseMessage>(message => { return message.StatusCode == System.Net.HttpStatusCode.BadRequest; }).RetryAsync(3));
    
    
                //服务中注册策略
                var reg2 = services.AddPolicyRegistry();
                //捕捉到异常HttpResponseMessage 且  NotFound  ,直接返回ok
                reg.Add("RetryBack", Policy.HandleResult<HttpResponseMessage>(message => { return message.StatusCode == System.Net.HttpStatusCode.NotFound; }).Fallback(new HttpResponseMessage() { StatusCode=System.Net.HttpStatusCode.OK}));
                #endregion
    
                #region 使用策略
                services.AddHttpClient("client1").AddPolicyHandlerFromRegistry("Retry3");
    
                //动态定义策略机制
                services.AddHttpClient("client2").AddPolicyHandlerFromRegistry((reg,mes)=> {
                    //这行代码意思如果是httpget 就使用Retry3策略,  如果不是就熔断不做任何处理
                    //
                    return mes.Method == HttpMethod.Get ? reg.Get<IAsyncPolicy<HttpResponseMessage>>("Retry3") : Policy.NoOpAsync<HttpResponseMessage>();
                });
                #endregion
                #endregion
    
                #region 3、捕获异常操作
                //直接返回
                //Policy.Handle<Exception>().Fallback()
                //熔断
                //Policy.Handle<Exception>().CircuitBreaker
                #endregion
    View Code

    上面代码主要指结合httpclient添加polly


    策略分类
    • 被动策略(异常处理、结果处理)
    程序出现异常,策略被动去做
     
    • 主动策略(超时处理、断路器、舱壁隔离、缓存)
    策略总动去做的
    策略状态

     使用策略的时候,策略设置为单例的模式,但是这些策略是有状态的。

    比如要对多个服务的熔断计数,那就需要多个熔断策略实例。

    策略组合  熔断-降级
                var breakPolicy = Policy<HttpResponseMessage>.Handle<HttpRequestException>().AdvancedCircuitBreakerAsync(
                    failureThreshold: 0.8,
                    samplingDuration: TimeSpan.FromSeconds(10),
                    minimumThroughput: 100,
                    durationOfBreak: TimeSpan.FromSeconds(20),
                    onBreak: (r, t) => { },
                    onReset: () => { },
                    onHalfOpen: () => { });
    
                var message = new HttpResponseMessage()
                {
                    Content = new StringContent("{}")
                };
                var fallback = Policy<HttpResponseMessage>.Handle<BrokenCircuitException>().FallbackAsync(message);
                var retry = Policy<HttpResponseMessage>.Handle<Exception>().WaitAndRetryAsync(3, i => TimeSpan.FromSeconds(1));
                var fallbackBreak = Policy.WrapAsync(fallback, retry, breakPolicy);
                services.AddHttpClient("httpv3").AddPolicyHandler(fallbackBreak);

    1、上面代码组合策略。    熔断-重试-降级

    10内有80%的错误请求,就熔断。熔断后重试三次,如果服务正常,则按正常处理,如果失败 则(降级)后返回一个空的http返回。
    ----------------------------------------------------------------------------------------------------------------
                var bulk = Policy.BulkheadAsync<HttpResponseMessage>(
                    //最大并发 处理 数量
                    maxParallelization: 30,
                    //如果不定义这个参数, 最大请求数超量,就会报错。定义了这个参数其他请求就会排队,如果排队大于20就在报错 
                    maxQueuingActions: 20,
                    //当我们请求被拒绝,被限流了  做的处理
                    onBulkheadRejectedAsync: contxt => Task.CompletedTask
                    );
    
                var message2 = new HttpResponseMessage()
                {
                    Content = new StringContent("{}")
                };
                var fallback2 = Policy<HttpResponseMessage>.Handle<BulkheadRejectedException>().FallbackAsync(message);
                var fallbackbulk = Policy.WrapAsync(fallback2, bulk);
                services.AddHttpClient("httpv4").AddPolicyHandler(fallbackbulk);

    2、上面代码组合策略。    限流-降级

     
  • 相关阅读:
    hdu 3714 Error Curves(三分)
    hdu 4717 The Moving Points(第一个三分题)
    hdu 4722 Good Numbers(规律题)
    分布式平台基础算法浅析
    Linux下通过管道杀死所有与tomcat相关的进程
    实习番外篇:解决C语言使用Makefile无法实现更好的持续集成问题
    SHELL脚本之awk妙用
    如何在CentOS7上安装Python3及对应问题
    欧拉定理和费马小定理
    最大公约和最小公倍数
  • 原文地址:https://www.cnblogs.com/wudequn/p/13169400.html
Copyright © 2011-2022 走看看