十一、一文搞定spring cloud重要成員--Hystrix(斷路器)
在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以相互呼叫(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign來呼叫。為了保證其高可用,單個服務通常會叢集部署。由於網路原因或者自身的原因,服務並不能保證100%可用,如果單個服務出現問題,呼叫這個服務就會出現執行緒阻塞,此時若有大量的請求湧入,Servlet容器的執行緒資源會被消耗完畢,導致服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統造成災難性的嚴重後果,這就是服務故障的“雪崩”效應。 為了解決這個問題,業界提出了斷路器模型。
是什麼
Netflix開源了Hystrix元件,實現了斷路器模式,SpringCloud對這一元件進行了整合。在微服務架構中,一個請求需要呼叫多個服務是非常常見的,較底層的服務如果出現故障,會導致連鎖故障。當對特定的服務的呼叫的不可用達到一個閥值(Hystric 是5秒20次) 斷路器將會被開啟。斷路開啟後,可用避免連鎖故障,fallback方法可以直接返回一個固定值。
具體使用
依賴
<!--斷路器依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <!--健康檢查依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--儀表盤依賴--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId> </dependency>
在restTemplate+ribbon方式下
-
改造service
在方法上加上@HystrixCommand註解。該註解對該方法建立了熔斷器的功能,並指定了fallbackMethod熔斷方法
@Service public class HelloService { @Resource RestTemplate restTemplate; @HystrixCommand(fallbackMethod = "error") public String helloService(){ return restTemplate.getForObject("http://user-service/hello",String.class); } public String error(){ return "error"; } }
-
開啟熔斷:啟動類
@SpringBootApplication @EnableEurekaClient //標識Eureka客戶端 @EnableHystrix //開啟斷路器 @EnableHystrixDashboard //開啟斷路器儀表盤 public class ConsumerRibboApplication { public static void main(String[] args) { SpringApplication.run(ConsumerRibboApplication.class, args); } //向程式的ioc注入一個bean: restTemplate;並通過@LoadBalanced註解表明這個restRemplate開啟負載均衡的功能。 @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); } //加入斷路器儀表盤,注入bean @Bean public ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); registrationBean.setLoadOnStartup(1); registrationBean.addUrlMappings("/actuator/hystrix.stream"); registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; } }
-
檢視儀表盤
-
設定超時時間(預設1s)
可以使用設定commandProperties屬性來設定:execution.isolation.thread.timeoutInMilliseconds
@HystrixCommand(fallbackMethod = "error", commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "500") }) public String helloService(){ return restTemplate.getForObject("http://user-service/hello",String.class); }
關閉超時設定:execution.timeout.enabled設為false
@HystrixCommand(fallbackMethod = "error", commandProperties = { @HystrixProperty(name = "execution.timeout.enabled", value = "false") }) public String helloService(){ return restTemplate.getForObject("http://user-service/hello",String.class); }
其它值得關注的屬性
circuitBreaker.requestVolumeThreshold:在給定的時間範圍內,方法應該被呼叫的次數
circuitBreaker.errorThresholdPercentage:在給定的時間範圍內,方法呼叫產生失敗的百分比
metrics.rollingStats.timeInMilliseconds:控制請求量和錯誤百分比的滾動時間週期
circuitBreaker.sleepWindowInMilliseconds:處於開啟狀態的斷路器要經過多長時間才會進入到半開狀態,進入半開狀態之後,將會再次嘗試失敗的原始方法。
在feign方式下
-
新增配置開啟斷路器
feign: hystrix: enabled: true #開啟斷路器
-
建立熔斷處理類,實現對應介面
@Component public class ErrorHander implements HelloAction { @Override public String hello() { return "feign error"; } }
-
介面指定熔斷處理類,fallback
@FeignClient(value = "user-service",fallback = ErrorHander.class) public interface HelloAction { @RequestMapping(value = "/hello",method = RequestMethod.GET) String hello(); }
4.設定超時時間
#hystrix斷路引數配置
hystrix:
command:
default: #default時為預設配置, 相關引數說明在 HystrixCommandProperties
execution:
isolation:
thread:
timeoutInMilliseconds: 60000
聚合多個Hystrix流
使用的是Netfilx的另外一個專案Turbine
依賴引入
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-turbine</artifactId> </dependency>
啟動類開啟
@EnableTurbine
新增配置
turbine:
app-config: service-1,service-2 #需要註冊的服務
cluster-name-expression: "'default'" #default表示收集叢集中的所有聚合流
原始碼地址:https://github.com/kinglead2012/myblog