Spring Cloud -- 斷路器(Hystrix)
為什麼需要 Hystrix?
在微服務架構中,我們將業務拆分成一個個的服務,服務與服務之間可以相互呼叫(RPC)。為了保證其高可用,單個服務又必須叢集部署。由於網路原因或者自身的原因,服務並不能保證服務的100%可用,如果單個服務出現問題,呼叫這個服務就會出現網路延遲,此時若有大量的網路湧入,會形成任務累計,導致服務癱瘓,甚至導致服務“雪崩”。為了解決這個問題,就出現斷路器模型。
Hystrix 是一個幫助解決分散式系統互動時超時處理和容錯的類庫, 它同樣擁有保護系統的能力.什麼是服務雪崩?
分散式系統中經常會出現某個基礎服務不可用造成整個系統不可用的情況, 這種現象被稱為服務雪崩效應. 為了應對服務雪崩, 一種常見的做法是手動服務降級. 而Hystrix的出現,給我們提供了另一種選擇.
Hystrix作用
1.斷路器機制
斷路器很好理解, 當Hystrix Command請求後端服務失敗數量超過一定比例(預設50%), 斷路器會切換到開路狀態(Open). 這時所有請求會直接失敗而不會發送到後端服務. 斷路器保持在開路狀態一段時間後(預設5秒), 自動切換到半開路狀態(HALF-OPEN). 這時會判斷下一次請求的返回情況, 如果請求成功, 斷路器切回閉路狀態(CLOSED), 否則重新切換到開路狀態(OPEN). Hystrix的斷路器就像我們家庭電路中的保險絲, 一旦後端服務不可用, 斷路器會直接切斷請求鏈, 避免傳送大量無效請求影響系統吞吐量, 並且斷路器有自我檢測並恢復的能力.
2.Fallback
Fallback相當於是降級操作. 對於查詢操作, 我們可以實現一個fallback方法, 當請求後端服務出現異常的時候, 可以使用fallback方法返回的值. fallback方法的返回值一般是設定的預設值或者來自快取.
3.資源隔離
在Hystrix中, 主要通過執行緒池來實現資源隔離. 通常在使用的時候我們會根據呼叫的遠端服務劃分出多個執行緒池. 例如呼叫產品服務的Command放入A執行緒池, 呼叫賬戶服務的Command放入B執行緒池. 這樣做的主要優點是執行環境被隔離開了. 這樣就算呼叫服務的程式碼存在bug或者由於其他原因導致自己所線上程池被耗盡時, 不會對系統的其他服務造成影響. 但是帶來的代價就是維護多個執行緒池會對系統帶來額外的效能開銷. 如果是對效能有嚴格要求而且確信自己呼叫服務的客戶端程式碼不會出問題的話, 可以使用Hystrix的訊號模式(Semaphores)來隔離資源.
service-order工程新增Maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
Rest方式使用斷路器
Rest請求方式介面改造
@HystrixCommand(fallbackMethod = "orderError")
public List<String> getOrderUserAll() {
return restTemplate.getForObject("http://service-member/getMemberAll", List.class);
}
public List<String> orderError() {
List<String> listUser = new ArrayList<String>();
listUser.add("not orderUser list");
return listUser;
}
@HystrixCommand 作用:服務發生錯誤,回撥方法。
在程式的啟動類ServiceRibbonApplication 加@EnableHystrix註解開啟Hystrix:
@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class ServiceOrderApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceOrderApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
["zhangsan","lisi","yushengjun","member-service埠號:8763"]
["not orderUser list"]
Fegin使用斷路器
Feign是自帶斷路器的,在D版本的Spring Cloud之後,它沒有預設開啟。需要在配置檔案中配置開啟它,在配置檔案加以下程式碼:
feign.hystrix.enabled=true
改造service-order-feign工程
@FeignClient(value="service-member",fallback=MemberFeignService.class)
public interface MemberFeign {
@RequestMapping("/getUserList")
public List<String> getOrderByUserList();
}
@Component
public class MemberFeignService implements MemberFeign {
public List<String> getOrderByUserList() {
List<String> listUser = new ArrayList<String>();
listUser.add("not orderUser list");
return listUser;
}
}
["zhangsan","lisi","yushengjun","member-service埠號:8763"]
當我們關閉service-member工程, 瀏覽器返回:
["not orderUser list"]