什麼是Polly? Polly是一個.NET彈性和瞬態故障處理庫.允許我們以非常順暢和線程安全的方式來執行諸如行重試,斷路,超時,故障恢復等策略。 Polly項目地址:https://github.com/App-vNext/Polly Polly提供多種彈性策略:重試(Retry),斷路器(Cir ...
什麼是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):