熔斷機制
熔斷機制是應對雪崩效應的一種微服務鏈路保護機制,當扇出鏈路的某個微服務出錯不可用或者響應時間太長時,會進行服務的降級,進而熔斷該節點微服務的調用,快速返回錯誤的響應信息。
當檢測該節點微服務調用響應正常后,恢復調用鏈路。
在SpringCloud框架里,熔斷機制通過Hystrix實現,Hystrix會監控微服務間調用的狀況,當失敗的調用到一定閥值,缺省是5秒內20次調用失敗,就會啟動熔斷機制。熔斷機制的注解是@HystrixCommand
參考大神寫的文章:https://martinfowler.com/bliki/CircuitBreaker.html
熔斷機制主要通過斷路器來實現
斷路器原理
斷路器狀態:
- Closed:熔斷器關閉狀態(所有請求返回成功)
- Open:熔斷器打開狀態(調用次數累計到達閾值或者比例,熔斷器打開,服務直接返回錯誤)
- Half Open:熔斷器半開狀態(默認時間過后,進入半熔斷狀態,允許定量服務請求,如果調用都成功,則認為恢復了,則關閉斷路器,反之打開斷路器)
斷路器的基本原理非常簡單。將受保護的函數調用包裝在斷路器對象中,該對象將監視故障。一旦故障達到一定閾值,斷路器將跳閘,並且所有進一步的斷路器調用都會返回錯誤,而根本不會進行受保護的調用。這個簡單的斷路器避免了在電路斷開時發出受保護的呼叫,但是當情況恢復正常時,將需要外部干預才能將其重置。對於建築物中的電路斷路器,這是一種合理的方法,但是對於軟件斷路器,可以讓斷路器本身檢測基礎調用是否再次正常工作。可以通過在適當的時間間隔后再次嘗試受保護的調用來實現這種自我重置行為,並在成功后重置斷路器。
服務熔斷案例
繼續使用前一章(【SpringCloud】Hystrix服務降級(十))的項目
1、在服務提供者模塊(test-springcloud-provider-payment8008)中,編輯業務類PaymentService,新增一下內容:
1 // 服務熔斷 2 @HystrixCommand(fallbackMethod = "paymentCircuitBreaker_fallback", 3 // 屬性設置參考:HystrixCommandProperties 4 commandProperties = { 5 // 是否開啟斷路器,默認true 6 @HystrixProperty(name = "circuitBreaker.enabled", value = "true"), 7 // 請求次數,默認20 8 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), 9 // 時間窗口期,默認5000 10 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), 11 // 失敗率到達多少后跳閘,默認50 12 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60") 13 }) 14 public String paymentCircuitBreaker(@PathVariable("id") Integer id){ 15 if(id < 0) { 16 throw new RuntimeException("======== id 不能為負數 ========="); 17 } 18 String serialNumber = UUID.randomUUID().toString(); 19 return Thread.currentThread().getName() + "\t" + "調用成功,流水號:" + serialNumber; 20 } 21 22 public String paymentCircuitBreaker_fallback(@PathVariable("id") Integer id){ 23 return " id 不能為負數,請稍后再試, id == " + id; 24 }
2、在controller中(PaymentController),新增以下方法:
1 @GetMapping(value = "/payment/hystrix/circuit/{id}") 2 public String paymentInfo_circuit(@PathVariable("id") Integer id) { 3 String result = paymentService.paymentCircuitBreaker(id); 4 log.info("result===" + result); 5 return result; 6 }
3、測試
1)啟動項目(test-springcloud-provider-payment8008)
2)訪問地址:http://localhost:8008/payment/hystrix/circuit/1,正常訪問
3)訪問地址:http://localhost:8008/payment/hystrix/circuit/-1,連續訪問改地址,
頁面顯示,服務降級,錯誤信息,繼續使之錯誤次數達到10次以上,
然后訪問地址:http://localhost:8008/payment/hystrix/circuit/1,可以看到服務還是不可用,
過一段時間,繼續訪問,發現服務可以