熔斷降級框架Polly在.Net Core中的應用及其封裝使用

熔斷降級

概念------爲什麼-----如何使用----運行原理------熔斷-----降級-----超時------重試----封裝 -----consul和polly整合到項目中

首先我們來明確一下,微服務架構的基本單位是微服務,也就主體是微服務----同時每一個微服務都有自己的結構。這些結構組合成了一個微服務(這屬於文件夾分層發)這個時候,那麼每一個微服務都會出現相同的結構。這個時候很多同學會有疑問,爲什麼各個微服務之間這些相同的文件不能夠進行通用呢,反而會出現這麼多冗餘。這樣做的原因,1、保證微服務的獨立性,2、保證微服務的穩定。我舉個例子:微服務就好比我們每一個人,我們每一個人就組成了一個社會架構,微服務和這種場景是類似的。大家都知道,每個人的結構都是一樣的。如果每個人結構都全部集中到一起。會出現什麼問題,大家可以想象一下。全部亂套了。同理,微服務也是一樣。所有微服務的第一要務就是保證獨立性。所以我這裏對微服務採用文件夾分層法。

對於什麼時候用程序集分層。先明白一下,每一個微服務都有自己的領域模型(也就是我們昨天說的問題和問題邊界)。如果多個微服務之間。存在不得不共享資源,共享資源是不易變化,且變化不影響每一個微服務的邏輯的時候。那麼我們就把這通用的邏輯抽取出來,用dll來分層進行引用,例如:微服務之間都需要通信,需要認證,需要限流,負載均衡等等。那麼咱們就把這一層稱作爲工具層。

什麼是熔斷

熔斷就是在被調用端出現宕機,和超時兩種情況出現的一種策略應對機制。

熔斷就好比保險絲,我們先來看一看保險絲的情況

爲什麼要使用熔斷

​ 1、服務調用出現異常(包括超時和宕機兩種情況)

​ 如果服務連續幾次都出現異常,那麼就將服務進行熔斷一段時間,

什麼是降級

爲什麼要使用降級

​ 1、服務主動降級(選擇性放棄)

​ 主動將服務進行進行異常返回

​ 2、服務異常降級

​ 如果服務調用出現超時或者宕機的情況,就按照自定義的策略進行返回。

項目中熔斷降級的目的是保證系統的彈性,使系統高可用

項目中如何運用熔斷降級

熔斷降級工具

​ 1、Polly

​ 2、Hystrix

微服務中如何使用Polly

主要功能

​ 重試(Retry)

​ 斷路器(Circuit-breaker)

​ 超時檢測(Timeout)

​ 緩存(Cache)

​ 降級(FallBack)

Polly官網地址

http://www.thepollyproject.org/

Polly安裝

​ Nuget Microsoft.Extensions.Http.Polly

Polly如何使用

​ 條件

​ 1、微服務項目

​ 2、Polly

​ 3、Polly http擴展

​ 步驟

​ 1、先通過nuget進行安裝

​ Microsoft.Extensions.Http.Polly

​ 2、然後在HttpClient後面添加擴展方法AddPolicyHandler()

​ 3、然後在團隊服務裏面,測試宕機,和超時情況

​ 3、先選擇熔斷策略

.AddPolicyHandler(Policy<HttpResponseMessage>.Handle<Exception>().CircuitBreakerAsync(3, TimeSpan.FromSeconds(10), (ex, ts) => {
                Console.WriteLine($"服務{name}斷路器開啓,異常消息:{ex.Exception.Message}");
                Console.WriteLine($"服務{name}斷路器開啓時間:{ts.TotalSeconds}s");
            }, () => {
                Console.WriteLine($"服務{name}斷路器重置");
            }, () => {
                Console.WriteLine($"服務{name}斷路器半開啓(一會開,一會關)");
            }))	

​ 5、然後選擇降級策略

var fallbackResponse = new HttpResponseMessage
{
	Content = new StringContent("系統出現異常,請稍後重試"),
	StatusCode = HttpStatusCode.GatewayTimeout
};

.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;
           }))	

​ 6、然後選擇重試策略

.AddPolicyHandler(Policy<HttpResponseMessage>
              .Handle<Exception>()
              .RetryAsync(options.RetryCount)
            )

​ 7、最後選擇超時機制

		 .AddPolicyHandler(Policy.TimeoutAsync<HttpResponseMessage>(TimeSpan.FromSeconds(options.TimeoutTime)));

Polly如何在項目中封裝

​ 條件

​ 1、IServiceCollection擴展類

​ 2、HttpClientPolly選項類

​ 步驟

​ 1、創建PollyHttpClientServiceCollectionExtensions類

       /// <summary>
        /// Httpclient擴展方法
        /// </summary>
        /// <param name="services">ioc容器</param>
        /// <param name="name">HttpClient 名稱(針對不同的服務進行熔斷,降級)</param>
        /// <param name="action">熔斷降級配置</param>
        /// <param name="TResult">降級處理錯誤的結果</param>
        /// <returns></returns>
        public static IServiceCollection AddHttpClientPolly(this IServiceCollection services,string name,Action<HttpClientPollyOptions> action)
        {
            // 1、創建選項配置類
            HttpClientPollyOptions options = new HttpClientPollyOptions();
            action(options);
       // 2、配置httpClient,熔斷降級策略
        services.AddHttpClient(name)
       //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;
    }	

​ 2、然後創建熔斷,降級,重試,超時HttpClientPollyOptions配置類

    /// <summary>
        /// 超時時間設置,單位爲秒
        /// </summary>
        public int TimeoutTime { set; get; }
    /// <summary>
    /// 失敗重試次數
    /// </summary>
    public int RetryCount { set; get; }

    /// <summary>
    /// 執行多少次異常,開啓短路器(例:失敗2次,開啓斷路器)
    /// </summary>
    public int CircuitBreakerOpenFallCount { set; get; }

    /// <summary>
    /// 斷路器開啓的時間(例如:設置爲2秒,短路器兩秒後自動由開啓到關閉)
    /// </summary>
    public int CircuitBreakerDownTime { set; get; }

    /// <summary>
    /// 降級處理(將異常消息封裝成爲正常消息返回,然後進行響應處理,例如:系統正在繁忙,請稍後處理.....)
    /// </summary>
    public HttpResponseMessage httpResponseMessage { set; get; }			

​ 3、封裝後的代碼調用

services.AddPollyHttpClient("tony",options => {
	options.TimeoutTime = 1;
	options.RetryCount = 3;
	options.CircuitBreakerOpenFallCount = 2;
	options.CircuitBreakerDownTime = 100;
	options.httpResponseMessage = fallbackResponse;
});
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章