在分布式微服務的架構下, 架構師往往面臨著可靠性與性能間的抉擇。 Circuit Breaker 提供了一個可同時兼顧可靠性與性能的解決方案。
在分布式微服務的架構下, 架構師往往面臨著可靠性與性能間的抉擇。
當來自某個微服務外部 Client 的遠端調用, 要求微服務處理一購買 100 張股票的訂單時。
架構師假如隻是根據 Time Out 來決定此筆交易的成功與失敗, 則整體的微服務的整體架構, 便會很難能同時兼顧性能與可靠性。
A. 當微服務的整體架構有一較好的性能, 卻會為可靠性帶來風險:
架構師所設計的微服務外部 Client 遠端調用的 Time Out 時間是 2000 ms。
但, 此次微服務外部 Client 遠端調用、微服務成功處理這 100 張股票的訂單并送回一确認成功的資訊到微服務外部 Client 時, 共花費了 3000 ms。
是以, 微服務外部 Client 會誤認為, 先前所發送的請求已因錯誤而 Time Out。
微服務外部 Client 便又重發了一次 100 張股票的訂單。
這樣的場景, 便使得微服務陷入一極為複雜的邏輯判斷: 微服務需判斷此 100 張股票的訂單為重發或新購?
這例子主要是說明了, 當架構師希望微服務的整體架構有一較好的性能時, 而将微服務外部 Client 遠端調用的 Time Out , 設計得無法展現出:
微服務 Client 遠端調用、微服務處理服務與微服務送回一确認成功的資訊到微服務外部 Client, 所需的總體時間時, 便會為整體微服務架構的可靠性帶來風險。
當微服務的整體架構有一較好的性能, 卻會為可靠性帶來風險:
Time Out < 微服務 Client 遠端調用所需的時間 + 微服務處理服務的時間+ 微服務送回一确認成功的資訊到微服務外部 Client 的時間。
B. 當微服務的整體架構有一較好的可靠性, 而使得整體微服務的性能不佳:
架構師所設計的微服務外部 Client 遠端調用的 Time Out 時間是:
微服務 Client 遠端調用、微服務處理服與微服務送回一确認成功的資訊到微服務外部 Client, 所需最長的總體時間的兩倍。
舉例:
微服務 Client 遠端調用、微服務處理服與微服務送回一确認成功的資訊到微服務外部 Client, 所需的平均總體時間為 2000 ms。
微服務 Client 遠端調用、微服務處理服與微服務送回一确認成功的資訊到微服務外部 Client, 所需的最長總體時間為 5000 ms。
微服務外部 Client 遠端調用的 Time Out 時間便是: 10000 ms。
架構師所設計的微服務外部 Client 遠端調用的 Time Out 時間是 10000 ms; 微服務有更充裕的時間處理服務, 因而可靠性獲得較好的保障, 但, 10000 ms 也許太長了, 而使得整體微服務的性能不佳。
是以, 在分布式微服務的架構下, 光設計 “ Time Out” 是不夠的。
這也是為什麼, 必需要在 Time Out 的架構下, 置入 Circuit Breaker 了。
C. Circuit Breaker: 同時能兼顧可靠性與性能
當架構師在微服務的 Client 與微服務間置入 Circuit Breaker 後, Circuit Breaker 将負責監控微服務的狀态, 而使得微服務 Client 不緻于一直還調用微服務, 當微服務已經無法運作時。
另一方面, 當在微服務的 Client 與微服務間置入 Circuit Breaker後, 微服務外部 Client 遠端調用的 Time Out 時間便是:
微服務 Client 遠端調用 Circuit Breaker 的時間 + Circuit Breaker 送回資訊到微服務外部 Client 的時間。
而這所需的時間便相當的短, 也許隻需 1~2 ms。
是以, Circuit Breaker 在整體微服務架構下, 扮演著相當重要的角色; 不僅保障了微服務整體的可靠性, 更不至于因保障了微服務整體的可靠性, 而犧掉牲了微服務整體的性能。
在 GitHub 上有許多關于 Circuit Breaker 的實作。
我将在讨論到 AKKA 時, 再來讨論 Circuit Breaker 的作法與實作。

圖一: Circuit Breaker