微服务架构中,根据业务将架构拆成一个个服务,服务与服务之间可以相互调用(RPC),SpringCloud中可以通过RestTemplate+Ribbon和Feign调用。为了保证高可用,单个服务通常会集群部署,由于网络等种种原因,服务不可能100%可用,如果单个服务出现问题,调用这个服务就会出现线程阻塞,此时若出现大量请求涌入,Servlet容器的线程资源会很快被消耗完毕,导致服务瘫痪。
服务与服务之间的依赖性,导致故障会传播,会对整个微服务系统造成灾难性的严重后果。这就是服务故障的雪崩效应。
为了解决这个问题,业界提出了断路器模型。
一、介绍
Netflix has created a library called Hystrix that implements the circuit breaker pattern. In a microservice architecture it is common to have multiple layers of service calls.
Netflix开源了Hystrix组件,实现了断路器模式。SpringCloud对其进行了整合。
在微服务架构中,一个请求调用多个服务是非常常见的。
较底层的服务如果出现故障,会导致连锁故障。当对特定的服务调用不可用达到一定的阀值(Hystrix默认是5秒20次),就会打开断路器。
断路打开后,可用避免连锁故障,Fallback可以直接返回一个固定值。
二、在Ribbon使用断路器
在ribbon项目中引入Hystrix.
1. 需要引入Hystrix的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
注意如果是F版本的SpringCloud,这里要引 spring-cloud-starter-netflix-hystrix而不是spring-cloud-starter-hystrix,否则启动会报错。
2.在启动类上开启@EnableHystrix注解
@SpringCloudApplication
@EnableDiscoveryClient
@EnableHystrix
public class RibbonApplication {
public static void main(String[] args) {
SpringApplication.run(RibbonApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
3. 在需要创建断路器的service方法上开启@HystrixCommand注解,并制定fallbackMethod方法
@Service
public class SayService {
@Autowired
RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "error")
public String saySomeWord(String name) {
return restTemplate.getForObject("http://SERVICE-HI/say?name="+name, String.class);
}
public String error(String name) {
return "[Error] sorry," + name;
}
}
这里我们不开启服务,然后通过Ribbon去调用服务 http://localhost:8764/say?name=long_tian
开启service-hi服务,过大概5秒再次访问
三、在Feign使用Hystrix
方法一:引入spring-cloud-starter-netflix-hystrix依赖,然后跟Ribbon中一样在Controller中的方法上开启@HystrixCommand注解,创建fallbackMethod。
方法二:Feign自带Hystrix。但是默认是关闭的,需要修改配置打开。
feign:
hystrix:
enabled: true
引入依赖,在FeignClient接口的@FeignClient注解上加上fallbanck指定类。该类要实现FeignClient接口。
@FeignClient(value = "service-hi", fallback = SchedualServiceHystric.class)
public interface SchedualServiceHi {
@RequestMapping(value="/say",method = RequestMethod.GET)
String sayHiFromClientOne(@RequestParam(value = "name") String name);
}
代码中的SchedualServiceHystric,实现了FeignClient,所以它变成了FeignClient的fallback类。将它注入到IoC容器。
@Component
public class SchedualServiceHystric implements SchedualServiceHi {
@Override
public String sayHiFromClientOne(String name) {
return "sorry,Mr."+name+",service failed.";
}
}
启动feign工程,service工程,访问http://localhost:8765/hello?name=long_tian
再关闭service工程,再次访问
说明断路器生效了。
四、Hystrix仪表盘
Hystrix Dashborad用于实时监控Hystrix的各项指标信息。
1.引入依赖
<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>
2.在程序启动类上开启注解@EnableHystrixDashboard
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
@EnableHystrix
@EnableHystrixDashboard
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
3. 访问 http://localhost:8765/hystrix,界面如下
HystrixDashboard支持三种监控方式:
默认的集群监控:通过URL http://turbine-hostname:port/turbine.stream 开启,实现对默认集群的监控。
制定的集群监控: 通过URL http://turbine-hostname:port/turbine.stream?cluster=[clusterName] 开启,实现对集群clusterName的监控。
单体应用的监控:通过URL http://hystrix-app:port/hystrix.stream 开启,实现对某个实例的监控。
* Delay:控制服务器上轮询监控信息的延迟时间,默认为2000毫秒,可以通过配置该属性来降低客户端的网络和CPU的消耗。
* Title:用于展示的标题。
这里我们通过http://localhost:8765/hystrix.stream 监控之前创建的Hystrix。
访问一次 http://localhost:8765/hello?name=long_tian 调用一次服务,可以看到调用成功一次。
关掉被调用的服务,访问,可以看到调用失败。
在监控界面有两个重要的图形信息:一个实心圆和一条曲线。
* 实心圆:
1. 颜色。颜色的变化代表了实例的健康程度,健康程度从绿色、黄色、橙色、红色递减。
2. 大小。表示请求流量发生变化,流量越大实心圆越大。
所以可以通过实心圆发现大量实例中的故障实例和高压实例。
* 折线:
用来记录2分钟内流量的相对变化情况。可以通过它可以观察留下的上升下降趋势。