10. Hystrix服务熔断
Hystrix关键特性:服务降级、服务熔断、服务限流
1. Hystrix服务熔断
熔断机制
是应对雪崩效应的一种微服务链路保护机制。当扇出链路的某个微服务出错不可用或者响应时间太长时会进行服务的降级,进而熔断该节点微服务的调用,快速返回错误的响应信息。当检测到该节点微服务调用响应正常后,恢复调用链路
。
在Spring Cloud框架里,熔断机制通过Hystrix实现。Hystrix会监控微服务间调用的状况,当失败的调用达到一定阈值,缺省是5秒内20次调用失败,就会启动熔断机制
。熔断机制的注解是@HystrixCommand
。
马丁福勒提出的服务熔断概念:马丁福勒博客中提到: 由上图可以看到服务熔断的三种状态:
- 熔断打开:请求不再进行调用当前服务,内部设置时钟一般为MTTR(平均故障处理时间)当打开时长达到所设置时钟则进入半熔断状态
- 熔断关闭:熔断关闭,不会对服务进行熔断
- 熔断半开:部分请求根据规则调用当前服务,如果请求成功且符合规则认为当前服务恢复正常,关闭熔断,恢复链路。
2. 断路器三个重要参数
断路器三个重要参数:快照时间窗
、请求总数阈值
、错误百分比阈值
2.1 快照时间窗
断路器确定是否打开需要统计一些请求和错误数据,而统计的时间范围就是快照时间窗,默认为最近的10s。
2.2 请求总数阈值
在快照时间窗内,必须满足请求总数阈值才有资格熔断,默认为20,意味着在10s内,如果该hystrix命令的调用次数不足20次,即使所有的请求都超时或其他原因失败,断路器都不会打开。
2.3 错误百分比阈值
当请求总数在快照时间窗内超过了阈值,比如发生了30次调用,如果在这30次调用中,有15次发生了超时异常,也就是超过50%的错误百分比,在默认设置50%阈值的情况下,这时候就会将断路器打开。
接下来看看几个参数在Hystrix服务熔断种如何配置。
3. Hystrix服务熔断配置
3.1 引入Hystrix依赖
pom引入hystrix依赖(具体版本根据自己环境决定):
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
<version>2.2.1.RELEASE</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.18</version>
</dependency>
3.2 启动类添加激活注解
3.3 yml
3.4 业务类处理
仍然还是在@HystrixCommand注解中进行配置,添加四个Hystrix新的属性配置。
@RestController
@RequestMapping("/order")
@Slf4j
public class OrderHystrixController {
@HystrixCommand(fallbackMethod = "circuitFallback", commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),//是否开启断路器
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),// 请求次数
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),// 时间窗口期
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60")// 失败率达到多少后跳
})
@GetMapping(value = "/hystrix/circuit/{id}")
public String paymentCircuit(@PathVariable("id") Integer id) {
if (id < 0) {
throw new RuntimeException("id不能为负数");
}
String serial = IdUtil.simpleUUID();
return "调用成功,线程池:" + Thread.currentThread().getName() + "访问paymentInfoTimeOut,serial=" + serial;
}
public String circuitFallback(Integer id) {
return "测试断路器,线程池:" + Thread.currentThread().getName() + "访问paymentInfoTimeOut,id=" + id;
}
}
意思就是在10s的窗口期内,发送十次请求,假如说有60%也就是6次都失败了,就激活断路器。 在controller中写出响应的调用,然后进行访问,如果十次中有六次及以上是负数,会发现,第11次时就算是正数仍然会进入fallback方法,因为此时进行了服务熔断。
而当他断路器激活以后,所有的请求都无法处理了,而过一段时间之后,断路器又会尝试着让少量的请求通过一下(也就是断路器进入了half-open状态),而如果请求仍然失败,断路器又会重新回到open状态,如果请求成功,断路器则会关闭。也就是链路恢复。
Tip:参数如果不写默认值是多少?其他还有哪些参数? hystrix源码:找到 hystrix-core.jar包下的HystrixCommandProperties类,可以看到相关参数及默认值
4. Hystrix断路器开启或者关闭的条件
- 当满足一定的阀值的时候 (默认10秒内超过20个请求次数)
- 当失败率达到一定的时候 (默认10秒内超过50%的请求失败)
- 到达以上阀值,断路器将会开启
- 当开启的时候,所有请求都不会进行转发
- 一段时间之后(默认是5秒) ,这个时候断路器是半开状态,会让其中一个请求进行转发如果成功,断路器会关闭,若失败,继续开启。