微服務架構:使用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封裝(實現負載均衡請求)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM