熔断器 Spring Cloud Hystrix
1 目标
- 理解Hystrix的作用
- 理解雪崩效应
- 知道熔断器的3个状态以及3个状态的切换过程
- 能理解什么是线程隔离,什么是服务降级
- 能实现一个局部方法熔断案例
- 能实现全局方法熔断案例
2 讲解
2.1 Hystrix 简介
Hystrix,英文意思是豪猪,全身是刺,刺是一种保护机制。Hystrix也是Netflix公司的一款组件。
Hystrix的作用是什么?
Hystrix是Netflix开源的一个延迟和容错库,用于隔离访问远程服务、第三方库、防止出现级联失败也就是雪崩效应。
2.2 雪崩效应
什么是雪崩效应?
1.微服务中,一个请求可能需要多个微服务接口才能实现,会形成复杂的调用链路。
2.如果某服务出现异常,请求阻塞,用户得不到响应,容器中线程不会释放,于是越来越多用户请求堆积,越来越多线程阻塞。
3.单服务器支持线程和并发数有限,请求如果一直阻塞,会导致服务器资源耗尽,从而导致所有其他服务都不可用,从而形成雪崩效应;
Hystrix解决雪崩问题的手段,主要是服务降级**(兜底)**,线程隔离;
2.3 熔断原理分析
熔断器的原理很简单,如同电力过载保护器。
熔断器状态机有3个状态:
1.Closed:关闭状态,所有请求正常访问
2.Open:打开状态,所有请求都会被降级。
Hystrix会对请求情况计数,当一定时间失败请求百分比达到阈(yu:四声)值(极限值),则触发熔断,断路器完全关闭
默认失败比例的阈值是50%,请求次数最低不少于20次
3.Half Open:半开状态
Open状态不是永久的,打开一会后会进入休眠时间(默认5秒)。休眠时间过后会进入半开状态。
半开状态:熔断器会判断下一次请求的返回状况,如果成功,熔断器切回closed状态。如果失败,熔断器切回open状态。
threshold reached 到达阈(yu:四声)值
under threshold 阈值以下
【Hystrix熔断状态机模型:配图】
翻译之后的图:
熔断器的核心:线程隔离和服务降级。
1.线程隔离:是指Hystrix为每个依赖服务调用一个小的线程池,如果线程池用尽,调用立即被拒绝,默认不采用排队。
2.服务降级(兜底方法):优先保证核心服务,而非核心服务不可用或弱可用。触发Hystrix服务降级的情况:线程池已满、请求超时。
线程隔离和服务降级之后,用户请求故障时,线程不会被阻塞,更不会无休止等待或者看到系统奔溃,至少可以看到执行结果(熔断机制)。
2.4 局部熔断案例
目标:服务提供者的服务出现了故障,服务消费者快速失败给用户友好提示。体验服务降级
实现步骤:
(1)引入熔断的依赖坐标:
在user-consumer
中加入依赖
<!--熔断器-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
(2)开启熔断的注解
修改user-consumer
的com.itheima.UserConsumerApplication
,在该类上添加@EnableCircuitBreaker
,代码如下:
注意:这里也可以使用@SpringCloudApplication
,写了@SpringCloudApplication
后,其他注解需要全部去掉。
(3)服务降级处理
在user-consumer
的com.itheima.controller.UserController
中添加降级处理方法,方法如下:
/****
* 服务降级处理方法
* @return
*/
public User failBack(Integer id){
User user = new User();
user.setUsername("服务降级,默认处理!");
return user;
}
在有可能发生问题的方法上添加降级处理调用,例如在queryById
方法上添加降级调用,代码如下:
(4)测试
将服务全部停掉,启动eureka-server
和user-consumer
,然后请求<http://localhost:18082/consumer/1>
测试效果如下:
2.5 其他熔断策略配置
1. 熔断后休眠时间:sleepWindowInMilliseconds
2. 熔断触发最小请求次数:requestVolumeThreshold
3. 熔断触发错误比例阈值:errorThresholdPercentage
4. 熔断超时时间:timeoutInMilliseconds
配置如下:
# 配置熔断策略:
hystrix:
command:
default:
circuitBreaker:
# 强制打开熔断器 默认false关闭的。测试配置是否生效
forceOpen: false
# 触发熔断错误比例阈值,默认值50%
errorThresholdPercentage: 50
# 熔断后休眠时长,默认值5秒
sleepWindowInMilliseconds: 10000
# 熔断触发最小请求次数,默认值是20
requestVolumeThreshold: 10
execution:
isolation:
thread:
# 熔断超时设置,默认为1秒
timeoutInMilliseconds: 2000
(1)超时时间测试
a.修改user-provider
的com.itheima.controller.UserController
的findById
方法,让它休眠3秒钟。
b.修改user-consumer
的application.yml,设置超时时间5秒,此时不会熔断。
c.如果把超时时间改成2000,此时就会熔断。
(2)熔断触发最小请求次数测试
a.修改user-provider
的com.itheima.controller.UserController
,在方法中制造异常,代码如下:
b.3次并发请求<http://localhost:18082/consumer/1>
,会触发熔断
再次请求<http://localhost:18082/consumer/2>
的时候,也会熔断,5秒钟会自动恢复。
并发请求建议使用jmeter
工具。
扩展-服务降级的fallback方法:
两种编写方式:编写在类上,编写在方法上。在类的上边对类的所有方法都生效。在方法上,仅对当前方法有效。
(1)方法上服务降级的fallback兜底方法
使用HystrixCommon注解,定义
@HystrixCommand(fallbackMethod="failBack")用来声明一个降级逻辑的fallback兜底方法
(2)类上默认服务降级的fallback兜底方法
刚才把fallback写在了某个业务方法上,如果方法很多,可以将FallBack配置加在类上,实现默认FallBack
@DefaultProperties(defaultFallback=”defaultFailBack“),在类上,指明统一的失败降级方法;
(3)案例
a.在user-consumer
的com.itheima.controller.UserController
类中添加一个全局熔断方法:
/****
* 全局的服务降级处理方法
* @return
*/
public User defaultFailBack(){
User user = new User();
user.setUsername("Default-服务降级,默认处理!");
return user;
}
b.在queryById
方法上将原来的@HystrixCommand
相关去掉,并添加@HystrixCommand
注解:
@HystrixCommand
@GetMapping(value = "/{id}")
public User queryById(@PathVariable(value = "id")Integer id){
//...略
return user;
}
c.在user-consumer
的com.itheima.controller.UserController
类上添加@DefaultProperties(defaultFallback = "defaultFailBack")
d.测试访问<http://localhost:18082/consumer/1>
,效果如下:
com.itheima.controller.UserController
完整代码:
3 小结
-
Hystrix的作用:用于隔离访问远程服务、第三方库、防止出现级联失败也就是雪崩效应。
-
理解雪崩效应:
properties
1.微服务中,一个请求可能需要多个微服务接口才能实现,会形成复杂的调用链路。
2.如果某服务出现异常,请求阻塞,用户得不到响应,容器中线程不会释放,于是越来越多用户请求堆积,越来越多线程阻塞。
3.单服务器支持线程和并发数有限,请求如果一直阻塞,会导致服务器资源耗尽,从而导致所有其他服务都不可用,从而形成雪崩效应;
- 知道熔断器的3个状态以及3个状态的切换过程
properties
1.Closed:关闭状态,所有请求正常访问
2.Open:打开状态,所有请求都会被降级。
Hystrix会对请求情况计数,当一定时间失败请求百分比达到阈(yu:四声)值(极限值),则触发熔断,断路器完全关闭
默认失败比例的阈值是50%,请求次数最低不少于20次
3.Half Open:半开状态
Open状态不是永久的,打开一会后会进入休眠时间(默认5秒)。休眠时间过后会进入半开状态。
半开状态:熔断器会判断下一次请求的返回状况,如果成功,熔断器切回closed状态。如果失败,熔断器切回open状态。
threshold reached 到达阈(yu:四声)值
under threshold 阈值以下
- 能理解什么是线程隔离,什么是服务降级
properties
1.线程隔离:是指Hystrix为每个依赖服务调用一个小的线程池,如果线程池用尽,调用立即被拒绝,默认不采用排队。
2.服务降级(兜底方法):优先保证核心服务,而非核心服务不可用或弱可用。触发Hystrix服务降级的情况:线程池已满、请求超时。
- 能实现一个局部方法熔断案例
properties
1.定义一个局部处理熔断的方法failBack()
2.在指定方法上使用@HystrixCommand(fallbackMethod = "failBack")配置调用
- 能实现全局方法熔断案例
properties
1.定义一个全局处理熔断的方法defaultFailBack()
2.在类上使用@DefaultProperties(defaultFallback = "defaultFailBack")配置调用
3.在指定方法上使用@HystrixCommand