1. 背景
在复杂的分布式 架构 的应用程序有很多的依赖,都会不可避免地在某些时候失败。高并发的依赖失败时如果没有隔离措施,当前应用服务就有被拖垮的风险。服务雪崩效应是一种因 服务提供者 的不可用导致 服务调用者 的不可用,并将不可用 逐渐放大 的过程.如果所示:
A服务调用B服务,B服务调用C服务,由于某种原因,B服务调用C服务不成功,B服务就会一直重试,同步等待会造成资源耗尽,结果B服务也不可用了,A也一直重试调用B服务,最后,A不可用,B不可用,C不可用,导致整个系统都不可用。
雪崩效应,是我们应该极力避免的。而springcloud家族防雪崩的利器是Hystrix
2. 初识Hystrix
1). 防雪崩利器
2). 基于Netflix对应的Hystrix
Hystrix的中文意思是豪猪,能保护自己不受天敌的伤害,代表了是一种防御的机制,这个Hystrix的框架不谋而合,提供一系列的服务容错保护机制。
3. Hystrix的作用
1). 服务降级(优先核心服务,非核心服务不可用或者弱可用)
a. 导入依赖
<!--服务容错-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
b. 启动类上加注解
@EnableCircuitBreaker
c. 使用Hystrix的服务容错
@HystrixCommand(fallbackMethod = "fallback")
@GetMapping("/getProductInfoList")
public String getProductInfoList(@RequestParam("number") Integer number) {
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForObject("http://localhost:8081/product/listForOrder", Arrays.asList("123456"), String.class);
// throw new RuntimeException("出异常了!!!");
}
private String fallback() {
return "太拥挤了, 请稍后再试~~";
}
d. 查看效果
注: 其实在服务容错使用场景中,最常用的是服务容错机制的超时设置,因为有些场景使用的是外网(第三方), 耗时往往比较长,加入注解就可实现
// 超时配置(超时时间: 3000ms)
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000")
})
2). 依赖隔离
3). 服务熔断
a. 核心:Circuit Breaker 断路器
b. 重点:微服务和分布式中,容错是必不可少的环节,通常的做法有两种,1. 重试机制:对于预期的短暂的故障可以使用重试是可以解决的,但是对于长时间的服务故障,重试依然没有任何意义。2. 断路器模式:将受保护的服务封装到可以监控故障的断路器对象中,当故障达到一定的值,就会阻断,断路器对象返回错误。结合一张图说明
状态机的三种状态:close,open, half open
三种状态之间的转换关系:close是熔断器的关闭状态,调用失败次数累计,到了一定的阈值或者一定的比例,就会启动熔断机制
open是熔断器的打开状态,此时,对服务都返回错误,它设计了一个时钟选项,默认的时钟到了这个时间之后,就会进入半熔断状态,就是half open
允许定量的服务请求,如果调用都成功或者一定的比例,则认为都回复了,就关闭熔断器,否则,就认为还没好,恢复熔断器打开状态。
@HystrixCommand(commandProperties = {
// 开启服务熔断
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"),
//请求数达到后才计算,设置在滚动时间窗口中断路器的最小请求数,这里设置的是10条
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"),
//休眠时间窗, 这个休眠时间窗结束以后,会将断路器设置为half open,尝试熔断请求命令,如果依然失败,就将断路器依然设置为代开状态,如果成功就设置为关闭状态
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"),
//错误率,设置熔断器打开的错误百分比条件,设置的是60,表示在滚动时间窗口中,如果发生了10次调用,在这10次调用中,7次发生了异常,错误70>60, 熔断器就设置为打开状态,否则就设置为关闭状态
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"),
})
sleepWindowInMilliseconds: 时间窗口,断路器确定要打开统计一些请求和错误数据的时候,它有个时间范围,时间范围被称为时间窗口,当断路器打开对主逻辑进行熔断之后,hystrix回启动一个休眠时间窗口,在这个时间窗内,降级的临时逻辑成为主逻辑,当休眠时间窗到期,短路器将进入半开状态,释放一次请求到原来的主逻辑上,如果此次请求正常返回,那么断路器继续闭合,主逻辑恢复,如果这次请求依然有问题,断路器则继续进入打开状态,休眠时间窗则持续计时.
4). 监控(Hystrix Dashboard)(对熔断进行可视化)
a. 导入依赖
<!--服务容错的可视化界面-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
b. 在启动类上加注解
@EnableHystrixDashboard
c. 查看服务页面
d. 进行服务的监控
几个颜色需要关注一下:颜色越偏向红色,代表这个服务越不健康
几个指标也需要注意: