緊接着上一篇說,我們繼續介紹Polly這個類庫html
若是調用某個目標服務出現過多超時、異常等狀況,能夠採起必定時間內熔斷該服務的調用,熔斷期間的請求將再也不繼續調用目標服務,而是直接返回,節約資源,提升服務的穩定性,熔斷週期結束後若是目標服務狀況好轉則恢復調用。git
注意:爲了服務的穩定性,在執行須要屢次 Retry重試策略的狀況下( 重試策略,感興趣的小夥伴能夠查看我上一篇,或者自行搜索),最好組合熔斷策略,預防可能存在的風險。github
熔斷器打開狀態,此時對目標服務的調用都直接返回錯誤,熔斷週期內不會走網絡請求,當熔斷週期結束時進入半開狀態;網絡
關閉狀態下正常發生網絡請求,但會記錄符合熔斷條件的連續執行次數,若是錯誤數量達到設定的閾值(若是在沒有達到閾值以前恢復正常,以前的累積次數將會歸零),熔斷狀態進入到打開狀態;框架
半開狀態下容許定量的服務請求,若是調用都成功(或必定比例)則認爲恢復了,關閉熔斷器,不然認爲還沒好,又回到熔斷器打開狀態;測試
// 在連續3次異常後熔斷,並保持1分鐘的熔斷狀態,調用者將收到斷路保護的異常信息 Policy .Handle<SomeExceptionType>() .CircuitBreaker(3, TimeSpan.FromMinutes(1));
private static int times = 0; public static void TestPolicy() { var circuitBreakerPolicy = Policy .Handle<Exception>() .CircuitBreaker( exceptionsAllowedBeforeBreaking: 4, // 連續4次異常 durationOfBreak: TimeSpan.FromMinutes(1), // 斷開1分鐘 onBreak: (exception, breakDelay) => // 斷路器打開時 Console.WriteLine($"熔斷: {breakDelay.TotalMilliseconds } ms, 異常: " + exception.Message), onReset: () => // 熔斷器關閉時 Console.WriteLine("熔斷器關閉了"), onHalfOpen: () => // 熔斷時間結束時,從斷開狀態進入半開狀態 Console.WriteLine("熔斷時間到,進入半開狀態") ); for (int i = 0; i < 12; i++) // 模擬屢次調用,觸發熔斷 { try { var result = circuitBreakerPolicy.Execute(Test); Console.WriteLine(result); } catch (Exception ex) { Console.WriteLine("try-catch:" + ex.Message); } Thread.Sleep(500); } } private static string Test() { times++; if (times % 5 != 0) // 模仿某些錯誤狀況下拋異常 { throw new Exception("exception message"); } return "success"; }
根據時間段內總請求數中的異常比例觸發熔斷:ui
var advancedCircuitBreakerPolicy = Policy .Handle<Exception>() .AdvancedCircuitBreaker( failureThreshold: 0.5, // 至少50%有異常則熔斷 samplingDuration: TimeSpan.FromSeconds(10), // 10秒內 minimumThroughput: 8, // 最少共有多少次調用 durationOfBreak: TimeSpan.FromSeconds(30), onBreak: (exception, breakDelay) => // 斷路器打開時 Console.WriteLine($"熔斷: {breakDelay.TotalMilliseconds } ms, 異常: " + exception.Message), onReset: () => // 熔斷器關閉時 Console.WriteLine("熔斷器關閉了"), onHalfOpen: () => // 熔斷時間結束時,從斷開狀態進入半開狀態 Console.WriteLine("熔斷時間到,進入半開狀態") );
能夠看到使用起來仍是 挺方便簡單的,能夠結合項目框架組合出不一樣玩法,哈哈哈,感興趣的同窗能夠自行古哥或者度娘哈。回見spa