十一、一文搞定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; } }
-
查看仪表盘
输入URL:http://localhost:8002/actuator/hystrix.stream
-
设置超时时间(默认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