本篇假設大家對hystrix的執行過程及原始碼有一定的了解,這裡介紹hystrix的熔斷器執行機制。
1.hystrix 熔斷器類結構
hystrixcircuitbreaker
作為介面定義,具體的實現有noopcircuitbreaker
和hystrixcircuitbreakerimpl
,其中noopcircuitbreaker
只是個空殼沒有具體的實現,相當於不熔斷。hystrixcircuitbreakerimpl
是主要的熔斷邏輯實現。
2.hystrix 熔斷器狀態
熔斷器有三個狀態closed
、open
、half_open
熔斷器預設關閉狀態,當觸發熔斷後狀態變更為open
,在等待到指定的時間,hystrix會放請求檢測服務是否開啟,這期間熔斷器會變為half_open
半開啟狀態,熔斷探測服務可用則繼續變更為closed
關閉熔斷器。
3.**視角
concurrenthashmapcircuitbreakersbycommand = new concurrenthashmap();
hystrix為每個commandkey都維護了乙個熔斷器,保持著對應的熔斷器,所以當new ***hystrixcommand()的時候依然能夠保持著原來熔斷器的狀態。
3.1 如何判定開啟熔斷
protected hystrixcircuitbreakerimpl(hystrixcommandkey key, hystrixcommandgroupkey commandgroup, final hystrixcommandproperties properties, hystrixcommandmetrics metrics)
private subscription subscribetostream() else else }}
}});
}
這裡面hystrixbreaker啟動的時候會訂閱hystrixcommandmetrics
的healthcountsstream
,每當healthcountsstream
蒐集到資料,都會觸發上面的onnext
方法,然後該方法做下面幾個判斷
1.當前請求量是否達到設定水位(請求量太小不做閥值控制)
2.當前的請求錯誤量是否達到閥值,達到後會將熔斷器狀態置為open
, circuitopened設定為當前時間戳表示開啟的時間。
3.2 attemptexecution
// mark that we're starting execution on the executionhook
// if this hook throws an exception, then a fast-fail occurs with no fallback. no state is left inconsistent
executionhook.onstart(_cmd);
/* determine if we're allowed to execute */
if (circuitbreaker.attemptexecution())
if (properties.circuitbreakerforceclosed().get())
if (circuitopened.get() == -1) else else
} else
}}這裡**判斷邏輯
1.判斷是否強制開啟熔斷器,是則return false,command不能執行
2.判斷是否強制關閉熔斷器,是則return true, command可執行
3.判斷熔斷器是否開啟circuitopened.get() == -1
表示沒有開啟,則return true,command可執行。
4.到這步證明已經開啟了熔斷器,那麼判斷是否可嘗試請求,如果可以同時會把熔斷器的狀態改為half_open
3.3 marksuccess&marknonsuccess
com.netflix.hystrix.abstractcommand#executecommandandobserve
private observableexecutecommandandobserve(final abstractcommand_cmd)
if (commandisscalar()) }};
final action0 markoncompleted = new action0() }};
final func1> handlefallback = new func1>()
};......省略干擾**.......
return execution.doonnext(markemits)
.dooncompleted(markoncompleted)
.onerrorresumenext(handlefallback)
.dooneach(setrequestcontext);
}
此處表示hystrixcommand執行的過程中對應的熔斷器狀態變更,上面**不難看出,當error的時候會觸發circuitbreaker.marknonsuccess();
,執行成功或者執行完成觸發circuitbreaker.marksuccess();
marknonsuccess
@override
public void marknonsuccess()
}
如果能執行到marknonsuccess,說明此時熔斷器是關閉狀態,或者嘗試放流階段。關閉狀態的話不做處理(未觸發熔斷),嘗試放流時,發現依然執行失敗,這裡講熔斷器狀態重新置為開啟狀態,並把circuitopened設定為當前的時間戳。
marksuccess
@override
public void marksuccess()
subscription newsubscription = subscribetostream();
activesubscription.set(newsubscription);
circuitopened.set(-1l);}}
能走到marksuccess說明熔斷器此時關閉或者放流階段,嘗試放流階段則講熔斷器關閉,設定circuitopened=-1,並重置指標統計。
4.結束了
到這裡熔斷器的介紹就結束了,回顧下主要有熔斷器如何開啟、如何關閉、幾個狀態的變更。乙個完整的熔斷器就此呈現在大家的面前。
Hystrix熔斷器(筆記)
當請求的微服務宕機,或者響應時間超時,會觸發熔斷機制,熔斷當前請求。hystrix 是乙個供分布式系統使用,提供延遲和容錯功能,保證複雜的分布系統在面臨不可避免的失敗時,仍能有其彈性。1 依賴 hystrix依賴,主要是用 hystrixcommand org.springframework.clo...
熔斷器Hystrix簡介
1 未使用統一的 退路方法,要在每個方法上配置 hystrixcommand fallbackmethod fallback hystrixcommand fallbackmethod fallback public object get pathvariable long id 退路 public...
Hystrix系列之熔斷器
熔斷器有三種狀態 關閉 開啟和半開 三者之間的轉換邏輯如下圖所示 熔斷器預設為 關閉 狀態 當失敗率或者失敗總量超過設定閾值,則變為 開啟 狀態,並開啟定時器 達到hystrixcommandproperties.circuitbreakersleepwindowinmilliseconds 設定的...