zoukankan      html  css  js  c++  java
  • 微服务架构:使用Polly实现熔断、降级

    参考:

    熔断降级--参考文档

    Polly官网地址

    通过 Polly 实现使用指数退避算法的 HTTP 调用重试 

    Polly 和 IHttpClientFactory一起使用

    HttpClientFactory 结合 Polly 轻松实现重试机制

     

    熔断

    熔断就是在被调用端出现宕机(死机 / 断开),和超时两种情况出现的一种策略应对机制,直接抛异常。

    只断开某一服务功能,也为了防止影响其他服务的整体运行。

    熔断就好比保险丝,我们先来看一看保险丝的情况

    举例:家里电器短路了只有家里跳闸了,而不影响整栋楼的电路。

    为什么要使用熔断

    1、服务调用出现异常(包括超时和宕机两种情况)

    如果服务连续几次都出现异常,那么就将服务进行熔断一段时间,程序知道这个服务是熔断状态就暂时不连接它,避免影响这个系统性能。

    降级

    保证核心功能可用,放弃一些非核心的外围功能减压,例如返回“系统繁忙”提示

    例如:电商系统中高峰期访问压力过大时,保证购物车和支付功能可用,暂停后面还有的请求(直接返回系统繁忙),或者暂停一些浏览功能

    1、服务主动降级(选择性放弃)

    主动将服务进行进行异常返回

    2、服务异常降级

    如果服务调用出现超时或者宕机的情况,就按照自定义的策略进行返回。

    项目中熔断降级的目的是保证系统的弹性,使系统高可用

    熔断与降级区别

    参考:

    熔断与降级的区别

    服务的熔断和降级的区别

    熔断是直接抛异常,降级是返回自定义信息。

    熔断是针对单一服务,降级是为了整个系统稳定而减少请求或者暂停外围非核心服务

    Polly主要功能

    重试(Retry)

    断路器(Circuit-breaker)

    超时检测(Timeout)

    缓存(Cache)

    降级(FallBack)

    Polly使用步骤

    1 nuget包安装

    先通过nuget进行安装,在AggregateService(聚合服务)、MicroService.Core(核心层/公共层/工具层)都需要安装:Microsoft.Extensions.Http.Polly

    2 添加Polly扩展类和方法

    然后在HttpClient后面添加扩展方法AddPolicyHandler()

    在MicroService.Core(核心服务/公共服务/工具层)中添加类

       /// <summary>
       /// 微服务中HttpClient熔断,降级策略扩展
       /// </summary>
       public static class PollyHttpClientServiceCollectionExtensions
       {
            /// <summary>
            /// Httpclient扩展Polly方法
            /// </summary>
            /// <param name="services">ioc容器</param>
            /// <param name="name">HttpClient 名称(针对不同的服务进行熔断,降级)</param>
            /// <param name="action">熔断降级配置</param>
            /// <param name="TResult">降级处理错误的结果</param>
            /// <returns></returns>
            public static IServiceCollection AddPollyHttpClient(this IServiceCollection services, string name,Action<PollyHttpClientOptions> action)
            {
                // 1、创建选项配置类
                PollyHttpClientOptions options = new PollyHttpClientOptions();
                action(options);
    
                // 2、配置httpClient,熔断降级策略
                services.AddHttpClient(name,client => {
                    client.Timeout = TimeSpan.FromSeconds(60);
                })
               //1.1 降级策略
               .AddPolicyHandler(Policy<HttpResponseMessage>.HandleInner<Exception>().FallbackAsync(options.httpResponseMessage, async b =>
               {
                   // 1、降级打印异常
                   Console.WriteLine($"服务{name}开始降级,异常消息:{b.Exception.Message}");
                   // 2、降级后的数据
                   Console.WriteLine($"服务{name}降级内容响应:{options.httpResponseMessage.Content.ToString()}");
                   await Task.CompletedTask;
               }))
                // 1.2 断路器策略
                .AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().CircuitBreakerAsync(options.CircuitBreakerOpenFallCount, TimeSpan.FromSeconds(options.CircuitBreakerDownTime), (ex, ts) => {
                    Console.WriteLine($"服务{name}断路器开启,异常消息:{ex.Exception.Message}");
                    Console.WriteLine($"服务{name}断路器开启时间:{ts.TotalSeconds}s");
                }, () => {
                    Console.WriteLine($"服务{name}断路器关闭");
                }, () => {
                    Console.WriteLine($"服务{name}断路器半开启(时间控制,自动开关)");
                }))
                // 1.3 重试策略
                .AddPolicyHandler(Policy<HttpResponseMessage>
                  .Handle<Exception>()
                  .RetryAsync(options.RetryCount)
                )
                // 1.4 超时策略
                .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(options.TimeoutTime)));
                
                return services;
            }
        }

    3 使用Polly方法

    在聚合服务的Startup类的ConfigureServices中测试宕机,和超时情况

                // 1、自定义异常处理(用缓存处理)
                var fallbackResponse = new HttpResponseMessage
                {
                    Content = new StringContent("系统正繁忙,请稍后重试"),// 内容,自定义内容
                    StatusCode = HttpStatusCode.GatewayTimeout // 504
                };
    
                // 1.2 封装之后的调用PollyHttpClient
                services.AddPollyHttpClient("mrico", options => {
                    options.TimeoutTime = 60; // 1、超时时间
                    options.RetryCount = 3;// 2、重试次数
                    options.CircuitBreakerOpenFallCount = 2;// 3、熔断器开启(多少次失败开启)
                    options.CircuitBreakerDownTime = 100;// 4、熔断器开启时间
                    options.httpResponseMessage = fallbackResponse;// 5、降级处理
                })
                 .AddHttpClientConsul<ConsulHttpClient>(); // 1.3、HttpClient下consul封装(实现负载均衡请求)
  • 相关阅读:
    char*”类型的值不能用于初始化“LPTSTR , Const char*”类型的值不能用于初始化“LPCTSTR
    LPCTSTR和LPTSTR和char *
    C++ char*,const char*,string的相互转换(转)
    vs2017 开发 C++ 操作mysql的动态库
    VS2017 创建C++Dll动态库(二)
    VS2017中托管C++程序调用托管C++生成的动态库,程序无法调试的问题(转)
    win10 MySQLroot 远程连接
    c++中c_str()的用法详解(转)
    【605】Python的开发环境相关 (不同版本python、pip)
    【604】Python class __dict__.update的使用
  • 原文地址:https://www.cnblogs.com/qingyunye/p/13550549.html
Copyright © 2011-2022 走看看