在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务通常会集群部署。由于网络原因或者自身的原因,服务并不能保证100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。
1.简介
Netflix开源了Hystrix组件,实现了熔断器模式,Spring Cloud 对这一组件进行了整合。 在微服务架构中,一个请求需要调用多个服务是非常常见的,如下图:
较底层的服务如果出现故障,会导致连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。
断路打开后,可用避免连锁故障,fallback方法可以直接返回一个固定值。
2.在Ribbon上使用熔断器
1.导入hystrix依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
2.注解@EnableHystrix 开启熔断器
@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix //开启断路器功能
public class ServiceRibbonApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceRibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
3.使用断路器
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
//使用断路器
@HystrixCommand(fallbackMethod = "ErrorMethod")
public String hi(String name){
return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);
}
//当服务不可用时会调用此方法并返回
public String ErrorMethod(String name){
return name + ",This is a error.";
}
}
3.在Feign上使用熔断器
1.Feign是自带断路器的,不过需要在配置文件打开,加以下代码.
feign.hystrix.enabled=true #这里IDEA不提示的
或者
feign:
hystrix:
enabled: true #这里IDEA不提示的
2.Hystrix支持回退的概念,当电路断开或出现错误时执行的默认代码路径。要为给定的 @FeignClient 启用回退,请将 fallback 属性设置为实现回退的类名.
@FeignClient(value = "service-hi",fallback = SchedualServiceHiImpl.class)
public interface SchedualServiceHi {
@RequestMapping(value = "/hi",method = RequestMethod.GET)
String sayHiFromClientOne(@RequestParam(value = "name") String name);
}
然后实现该接口方法即可.
@Service
public class SchedualServiceHiImpl implements SchedualServiceHi {
@Override
public String sayHiFromClientOne(String name) {
return name + ",This is a error.";
}
}
3.如果需要访问导致回退触发的原因,可以使用 @FeignClient 内的 fallbackFactory 属性,注意此时不要再使用 fallback 属性。
@FeignClient(value = "service-hi",fallbackFactory = HystrixClientFallbackFactory.class)
public interface SchedualServiceHi {
@RequestMapping(value = "/hi",method = RequestMethod.GET)
String sayHiFromClientOne(@RequestParam(value = "name") String name);
}
然后实现FallbackFactory接口即可.
@Component
public class HystrixClientFallbackFactory implements FallbackFactory<SchedualServiceHi> {
@Override
public SchedualServiceHi create(Throwable throwable) {
return new SchedualServiceHi() {
@Override
public String sayHiFromClientOne(String name) {
return name +"!"+ throwable.getMessage();
}
};
}
}
4.使用 Hystrix Dashboard 监控熔断器的状态
Hystrix Dashboard 是监控熔断器状况的一个组件,提供了数据监控和友好的图形化展示界面。
1.在Ribbon中使用 Hystrix Dashboard
在加入spring-cloud-starter-hystrix依赖的基础上,加入下面2个必需的依赖.
<!--断路器仪表盘-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
在主程序启动类已经加上 @EnableHystrix 的基础上加入@EnableHystrixDashboard 注解。完整代码如下.
@@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableHystrixDashboard
public class ServiceRibbonApplication {
启动程序,访问 http://localhost:8765/hystrix.stream 浏览器上会显示熔断器的数据指标,访问 http://localhost:8765/hystrix 浏览器会显示 Hystrix Dashboard 的界面。如下图。在界面上依次填写图示数据,点击"Monitor Stream",进入页面。
Hystrix Dashboard 官方文档
2.在Feign中使用 Hystrix Dashboard
加入下面3个起步依赖。虽然Feign自带hystrix,但自带的不是起步依赖,所以还是要加.
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-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-hystrix-dashboard</artifactId>
</dependency>
在启动程序上加 @EnableHystrixDashboard 注解开启Hystrix Dashboard,完整代码.
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrixDashboard
@EnableHystrix
public class ServiceFeignApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceFeignApplication.class, args);
}
}
只需要上面两步即可开启 Hystrix Dashboard 功能。
参考方志朋《深入理解Spring Cloud与微服务构建》