服務熔斷 類似現實生活中的“保險絲“,當某個異常條件被觸發,直接熔斷保險絲來起到保護電路的作用,
熔斷的觸發條件可以依據不同的場景有所不同,比如統計一個時間窗口內失敗的調用次數。
1.斷路器狀態機:
Closed:熔斷器關閉狀態(所有請求返回成功)
Open:熔斷器打開狀態(調用次數累計到達閾值或者比例,熔斷器打開,服務直接返回錯誤)
Half Open:熔斷器半開狀態(默認時間過后,進入半熔斷狀態,允許定量服務請求,如果調用都成功,則認為恢復了,則關閉斷路器,反之打開斷路器)
2.斷路器原理(不讓客戶端“裸調“服務器的rpc接口,而是在客戶端包裝一層。就在這個包裝層里面,實現熔斷邏輯):
public class CommandHelloWorld extends HystrixCommand<String> { private final String name; public CommandHelloWorld(String name) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.name = name; } @Override protected String run() { //關鍵點:把一個RPC調用,封裝在一個HystrixCommand里面 return "Hello " + name + "!"; } } //客戶端調用:以前是直接調用遠端RPC接口,現在是把RPC接口封裝到HystrixCommand里面,它內部完成熔斷邏輯 String s = new CommandHelloWorld("World").execute()
缺省的,上面的HystrixCommand是被扔到一個線程中執行的,也就是說,缺省是線程隔離策略。
還有一種策略就是不搞線程池,直接在調用者線程中執行,也就是信號量的隔離策略。
3.熔斷參數配置:
circuitBreaker.requestVolumeThreshold //滑動窗口的大小,默認為20
circuitBreaker.sleepWindowInMilliseconds //過多長時間,熔斷器再次檢測是否開啟,默認為5000,即5s鍾
circuitBreaker.errorThresholdPercentage //錯誤率,默認50%
每當20個請求中,有50%失敗時,熔斷器就會打開,此時再調用此服務,將會直接返回失敗,不再調遠程服務。直到5s鍾之后,重新檢測該觸發條件,判斷是否把熔斷器關閉,或者繼續打開。
4.demo:
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class FeignClientTestController {
@HystrixCommand(commandProperties = { @HystrixProperty(name = "circuitBreaker.enabled",value = "true"), @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60") })
public String serverMethod() {
return null;
}
public String defaultFallback() {
return "服務器開小差了";
}
}
提問:前面第5篇講到了Hystrix的服務降級,跟本篇的熔斷達到的結果一樣,都是返回預定的回調方法,那么服務熔斷跟降級到底有什么區別呢?
個人總結:服務降級:當服務內部出現異常情況,將觸發降級,這個降級是每次請求都會去觸發,走默認處理方法defaultFallback
服務熔斷:在一定周期內,服務異常次數達到設定的閾值或百分比,則觸發熔斷,熔斷后,后面的請求將都走默認處理方法defaultFallback