1. 程式人生 > >Polly的多種彈性策略介紹和簡單使用

Polly的多種彈性策略介紹和簡單使用

故障 廣泛 forever 影響 結合 ssim 封裝 n) csharp

什麽是Polly?
Polly是一個.NET彈性和瞬態故障處理庫.允許我們以非常順暢和線程安全的方式來執行諸如行重試,斷路,超時,故障恢復等策略。

Polly項目地址:https://github.com/App-vNext/Polly

Polly提供多種彈性策略:重試(Retry),斷路器(Circuit-breaker),超時檢測(Timeout),緩存(Cache),降級(FallBack)

重試(Retry):

前置條件:許多故障是短暫的,並且可能在短暫延遲後自我糾正
政策如何緩解:允許配置自動重試機制

斷路器(Circuit-breaker):
前置條件:當系統繁忙時,快速響應失敗比讓用戶一直等待更好,保護故障系統不受過載的影響可以幫助它恢復
政策如何緩解:故障超過某個預先配置的閾值時,阻塞執行一段時間。

超時檢測(Timeout):
前置條件:超過一定的等待,成功的結果是不可能的
政策如何緩解:保證調用者不必等待超時

隔板隔離(Bulkhead Isolation):
前置條件:當進程發生故障時,備份的多個失敗調用可以輕易地淹沒主機中的資源(例如線程/ CPU)。故障下遊系統還可能導致上遊“備份”失敗的呼叫,兩者都有可能導致故障過程導致更廣泛的系統崩潰
政策如何緩解:將受管理的操作限制在固定的資源池中,隔離它們影響其他資源的可能性

緩存(Cache):
前置條件:不經常更新的數據。
政策如何緩解:首次加載時,把響應數據進行緩存;如果緩存中存在,則從緩存中獲取數據;

降級(FallBack):


前置條件:操作仍然會失敗 - 當發生這種情況時你會做什麽
政策如何緩解:定義在失敗時返回的替代值(或要執行的操作)

策略包裝(PolicyWrap):
前置條件:不同故障需要不同的策略; 彈性意味著使用組合
政策如何緩解:允許靈活組合上述任何策略

代碼示例:

重試(Retry):

            //PollyException:此類文件是我自己定義的異常類
            //Policy policy = Policy.Handle<PollyException>().Retry();  //重試一次
            //Policy policy = Policy.Handle<PollyException>().Retry(10);//重試n次,本次是重試10次
            //Policy policy = Policy.Handle<PollyException>().Retry(10, (exception, retryCount, context) => //重試n次,在每次重試時調用下面代碼
            //{
            //    //每次重試都會執行這裏面的代碼
            //    //做些操作
            //});
            //Policy policy = Policy.Handle<PollyException>().RetryForever();  //一直重試直到成功
            Policy policy = Policy.Handle<PollyException>().WaitAndRetry(new[]
              {
                TimeSpan.FromSeconds(1),//等待1秒重試一次
                TimeSpan.FromSeconds(2),//等待2秒重試一次
                TimeSpan.FromSeconds(3) //等待3秒重試一次
              });  //重試3次,每次持續等待時間分別為1秒,2秒,3秒
            try
            {
                policy.Execute(() =>
                {
                    Console.WriteLine("開始任務");
                    int s = new Random().Next(0, 100);
                    if (s % 3 != 0)
                    {
                        throw new PollyException("出錯啦-" + s);
                    }
                    Console.WriteLine("完成任務" + s);
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

  

  

斷路器(Circuit-breaker):

            ISyncPolicy policy = Policy.Handle<PollyException>().CircuitBreaker(6, TimeSpan.FromSeconds(10));
            while (true)
            {
                try
                {
                    policy.Execute(() =>
                    {
                        Console.WriteLine("開始執行");
                        int s = new Random().Next(0, 100);
                        if (s % 10 != 0)
                        {
                            throw new PollyException("出錯啦-" + s);
                        }
                        Console.WriteLine("結束執行" + s);
                    });
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }

                Thread.Sleep(1000);
            }
//短路保護 出現了6次故障之後,直接給我們爆出了短路保護的異常,“The circuit is now open and is not allowing calls”

  請註意,斷路器策略會重新拋出所有異常,甚至是已處理的異常。斷路器用於測量故障並在發生太多故障時斷開電路,但不會重新編排重試。根據需要將斷路器與重試策略相結合。

策略包裝(PolicyWrap):

可以把多個ISyncPolicy合並到一起執行
policy3= policy1.Wrap(policy2);
執行policy3就會把policy1、 policy2封裝到一起執行

            Policy policyRetry = Policy.Handle<PollyException>().Retry(3);
            Policy policyFallback = Policy.Handle<PollyException>()
            .Fallback(() =>
            {
                Console.WriteLine("降級");
            });
            Policy policy = policyFallback.Wrap(policyRetry);
            policy.Execute(() =>
            {
                Console.WriteLine("開始任務");
                int s = new Random().Next(0, 100);
                if (s % 10 != 0)
                {
                    throw new PollyException("出錯-" + s);
                }
                Console.WriteLine("完成任務-" + s);
            });
//重試3次,還出錯就降級

  

超時檢測(Timeout):

            Policy policy = Policy.Handle<Exception>() //定義所處理的故障
            .Fallback(() =>
            {
                Console.WriteLine("執行出錯");
            });
            policy = policy.Wrap(Policy.Timeout(2, TimeoutStrategy.Pessimistic));
            policy.Execute(() =>
            {
                Console.WriteLine("開始任務");
                Thread.Sleep(5000);
                Console.WriteLine("完成任務");
            });

 超時處理不能簡單的鏈式調用 ,要用到Wrap()

降級(FallBack):

           //如果正常業務代碼出現異常,則執行降級業務代碼
            Action fallbackAction = () =>
            {
                //執行降級業務代碼
                Console.WriteLine("執行出錯-降級");
            };
            Policy policy = Policy.Handle<PollyException>()
            .Fallback(fallbackAction);
            policy.Execute(() =>
            {
                //正常業務代碼
                Console.WriteLine("開始任務");
                int s = new Random().Next(0, 100);
                if (s % 3 != 0)
                {
                    throw new PollyException("出錯啦-" + s);
                }
                Console.WriteLine("完成任務" + s);
            });

 緩存(Cache):

 隔板隔離(Bulkhead Isolation):

 

Polly的多種彈性策略介紹和簡單使用