Hystrix学习总结
Hystrix学习总结
雪崩效应
在微服务应用中,一个请求可能会调用多个微服务,从而形成复杂的调用链路;而当链路中的某一个微服务出现问题时(服务调用响应时间过长或者服务不可用),调用这个服务的请求也会被阻塞,对这个服务的调用会占用越来越多的系统资源,进而引起系统崩溃,这句是所谓的雪崩效应。
解决方法
解决雪崩效应主要有3种方法:
服务熔断
当扇出链路的某个微服务不可用或者响应时间过长时,暂时切断对这个微服务的调用,进行服务降级,返回错误信息;等到这个服务可以被正常调用时,恢复对它的调用。
服务熔断的核心在于切断对服务的调用,另外服务熔断和降级一般是同时使用的,Hystrix就是同时使用的。
服务降级
服务降级是当服务出问题或者影响到核⼼流程的性能时,暂时将服务屏蔽掉,待⾼峰或者问题解决后再打开。
服务降级一般是当某个服务熔断之后,此服务将不再被调用,我们可以准备⼀个本地的fallback回调,返回⼀个缺省值;虽然服务水平降低了,但是还是可用的。
服务限流
服务降级是通过暂时关掉服务来解决问题的,但是有些核心服务不能这样做,不能直接关掉;此时可以通过限流来解决,在流量高峰期限制一次最多能处理的请求,从而避免流量太多,服务无法处理这么多请求直接挂掉。
Hystrix
Hystrix介绍
Netflix开源的一个组件库,可以防止微服务调用中出现的级联错误,提供微服务系统的可用性。
Hystrix使用
1、引入Hystrix的依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
2、启动类上添加@EnableCircuitBreaker注解
@EnableCircuitBreaker //开启熔断器
3、定义服务降级处理方法,并把业务方法和服务降级方法关联起来
/**
* 提供者模拟处理超时,调用方法添加Hystrix控制
* 适用@HystrixCommand注解进行熔断控制
* @param userId
* @return
*/
@HystrixCommand(threadPoolKey = "findResumeOpenStateTimeout", //线程池唯一标识,要保持唯一
threadPoolProperties = { //线程池细节属性配置
@HystrixProperty(name = "coreSize", value = "1"), //线程数
@HystrixProperty(name = "maxQueueSize", value = "20"), //等待队列长度
}, commandProperties = { //每一个属性都是HystrixProperty
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000")},
fallbackMethod = "myFallBack" //降级方法
)
@GetMapping("/checkStateTimeout/{userId}")
public Integer findResumeOpenStateTimeout(@PathVariable Long userId) {
//使用了ribbon负载均衡,直接调用即可
String url = "http://lagou-service-resume/resume/openState" + userId;
Integer forObject = restTemplate.getForObject(url, Integer.class);
return forObject;
}
/**
* 定义降级方法,返回预设默认值,该方法的形参和返回值需要和原始方法保持一致
*
* @return
*/
public Integer myFallBack(Long userId) {
//兜底数据
return -123333;
}
舱壁模式
默认情况下Hystrix有一个线程池,里面有10个线程,为所有添加了@HystrixCommand注解的方法提供线程,如果这些方法接收的请求超过了10个,其它请求就只能等待或者拒绝连接。
如果不进行其它设置,10个线程很快就会被用完,那么其它请求就只能等待或者拒绝了,为了解决这个问题,Hystrix采用的解决方法是为每一个控制方法创建一个线程池,这被称为舱壁模式。
设置如下,threadPoolKey必须唯一,不然就是共用一个线程池了,coreSize和maxQueueSize则是设置了线程池线程数和线程池等待队列长度。
@HystrixCommand(threadPoolKey = "findResumeOpenStateTimeout", //线程池唯一标识,要保持唯一
threadPoolProperties = { //线程池细节属性配置
@HystrixProperty(name = "coreSize", value = "1"), //线程数
@HystrixProperty(name = "maxQueueSize", value = "20"), //等待队列长度
})
工作流程
跳闸、自我修复机制
前面已经提到了Hystrix是一个断路器,可用用来进行服务熔断,那么什么时候才会熔断呢?
Hystrix的工作流程如下图所示:
- 当调用出现问题的时候,Hystrix会开启一个时间窗,默认为10s
- Hystrix会统计在这个时间窗内是否达到了最小请求数,如果没有达到,会重置统计信息,等调用再次出现问题,重新开始统计;
- 如果达到了最小请求数,就统计失败的请求数在所有请求数中的占比是否达到阈值,如果没有达到,同样也会重置统计信息,回到第一步;
- 如果达到阈值,就会跳闸,然后开启一个活动窗口,默认是5s,每隔5s,Hystrix会让一个请求通过,到达那个问题服务,看是否调用成功,如果成功,整个流程回到第一步,如果没有成功,流程回到第3步;
上面提到的窗口时间是可以在@HystrixCommand注解的commandProperties中进行配置的
commandProperties = { //熔断细节配置,每个属性都是一个HystrixProperty
//统计时间窗口定义
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "20000"),
//统计时间窗口内的最小请求数
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "8000"),
//统计时间窗口内的错误数量百分比阈值
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "2"),
//自我修复时的活动窗口长度
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "3000")
},
上面的配置也可以在yml文件中进行配置
hystrix:
command:
default:
circuitBreaker:
#强制打开熔断器,设置为true,强制断路器进入打开状态,将会拒绝所有请求,默认为false
forceOpen: false
# 触发熔断错误⽐例阈值,默认值50%
errorThresholdPercentage: 50
# 熔断后休眠时⻓,默认值5秒
sleepWindowInMilliseconds: 3000
# 熔断触发最⼩请求次数,默认值是20
requestVolumeThreshold: 2
execution:
isolation:
thread:
# 熔断超时设置,默认为1秒
timeoutInMilliseconds: 2000
断路监控
Hystrix正常工作时会显示UP状态,跳闸后会显示为CIRCUIT_OPEN状态;通过SpringBoot提供的健康检查可以观察Hystrix跳闸的状态,首先需要开启配置,当然也需要引入actuator的依赖
# springboot中暴露健康检查等断点接⼝
management:
endpoints:
web:
exposure:
include: "*"
# 暴露健康接⼝的细节
endpoint:
health:
show-details: always
等启动后,在浏览器输入http://localhost:8090/actuator/health就可以看到状态了(前面的地址需要改为你自己的地址),接口返回的数据如下图,可以看到此时是正常工作的状态。
上面我们通过SpringBoot提供的监控检查功能可以看到Hystrix的工作状态,但是都是通过请求接口返回数据来看的,略有麻烦,实际上还可以通过Hystrix Dashboard来观察Hystrix的状态。
1、引入Hystrix dashboard依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
2、启动类添加注解@EnableHystrixDashboard注解,激活仪表盘
@EnableHystrixDashboard //激活仪表盘
3、注册监控Servlet
/**
* 监控Servlet,监控数据来自于这个微服务
* @return
*/
@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;
}
4、
输入监控的微服务断点地址http://localhost:8090/actuator/hystrix.stream,即可看到Hystrix的详细信息。
聚合监控
参考资料
- 《某训练营课程》