概念
在分布式系統中,一種不可避免的情況就是某些服務會出現故障,導致依賴他們的其他服務出現遠程調度的線程問題(雪崩效應)。而Hystrix提供的熔斷器,通過隔離服務的訪問點,能阻止這種分布式系統中出現的聯動故障,並提供故障的解決方案,從而提高了整個分布式系統的彈性。
設計原則
1、防止單個服務的故障耗盡整個服務的servlet容器的線程資源
2、快速失敗機制,如果某個服務出現故障則調用該服務的請求快速失敗,而不是線程等待
3、提供回退方案
4、使用熔斷機制,防止故障擴散到其他服務
5、提供熔斷器的監控組件Hystrix Dashboard,實時監控熔斷器狀態。提供Turbine聚合多喝Dashboard
工作機制
1、當某個API接口失敗的次數在一定時間內小魚設定的閥值時,熔斷器處於關閉狀態,該API正常提供服務。
2、當失敗次數大於設定的閥值的時候,Hystrix判定改API接口出現故障,打開熔斷器,這時候該請求API接口會執行快速失敗的邏輯(fallback回退的邏輯)而不執行業務邏輯,請求的線程不會處於阻塞狀態。
3、處於打開狀態的熔斷器,一段時間后會處於半打開狀態,並將一定數量的請求執行業務邏輯,剩余的請求會執行快速失敗。若執行的業務邏輯請求失敗,則熔斷器繼續打開,若成功則熔斷器關閉。
RestTemplate+Ribbon上使用熔斷器
1、引入依賴starter-hystrix后,在啟動類加上@EnableHystrix注解就可以開啟熔斷器功能
2、在方法上添加@HystrixCommand注解,設置fallBackMethod屬性,指定fallback回調,最好返回一些靜態字符串,不需要處理發雜邏輯什么的,這樣可以方便執行快速失敗,釋放線程資源。
Feign上使用熔斷器
1、配置文件啟用
feign: hystrix: enabled: true
2、定義快速失敗處理類
public class Hystrix implements EurekaClientFeign { @Override public String sayHiFromClientEureka(String name) { return "hi, " + name + ", sorry error!"; } }
3、@FeignClient注解的fallback配置加上快速失敗的處理類
@FeignClient(value = "hi-service", configuration = FeignConfig.class, fallback = Hystrix.class) public interface EurekaClientFeign { @GetMapping(value = "/hi") String sayHiFromClientEureka(@RequestParam(value = "name") String name); }
Hystrix Dashboard監控熔斷器狀態
本案例使用Feign講解
1、添加依賴:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、啟動類添加@EnableHystrixDashboard注解和ServletRegistrationBean配置
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrixDashboard
@EnableCircuitBreaker
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
public ServletRegistrationBean getServlet() {
HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
registrationBean.setLoadOnStartup(1);
registrationBean.addUrlMappings("/hystrix.stream");
registrationBean.setName("HystrixMetricsStreamServlet");
return registrationBean;
}
}
3、訪問監控后台
http://localhost:8765/hystrix.stream
http://localhost:8765/hystrix
可以看到單體應用的監控
使用Turbine聚合監控
默認的集群監控:通過URL:http://turbine-hostname:port/turbine.stream開啟,實現對默認集群的監控。
指定的集群監控:通過URL:http://turbine-hostname:port/turbine.stream?cluster=[clusterName]
單體應用的監控:通過URL:http://hystrix-app:port/hystrix.stream開啟,實現對具體某個服務實例的監控。