什么是Hystrix
Hystrix是一个通过资源隔离实现服务熔断降级的中间件
Hystrix的作用
- 熔断
- 降级
Hystrix原理
处理流程,我下面的贴图来自GitHub:流程图
这里我又画了一个简化版如下图
流程解释:
- 构造一个 HystrixCommand或HystrixObservableCommand对象,用于封装请求,并在构造方法配置请求被执行需要的参数;
- 执行命令,Hystrix提供了4种执行命令的方法,后面详述;
- 判断是否使用缓存响应请求,若启用了缓存,且缓存可用,直接使用缓存响应请求。Hystrix支持请求缓存,但需要用户自定义启动;
- 判断熔断器是否打开,如果打开,跳到第8步;
- 判断线程池/队列/信号量是否已满,已满则跳到第8步;
- 执行HystrixObservableCommand.construct()或HystrixCommand.run(),如果执行失败或者超时,跳到第8步;否则,跳到第9步;
- 统计熔断器监控指标;这里至少需要知道两个指标,只有这两个指标同时达到阈值的时候,才会发生熔断
- 滚动窗口时间内请求量
- 滚动窗口时间内发生错误的请求量
- 走Fallback备用逻辑
- 返回请求响应
资源隔离
通过三个角度讲一下资源隔离的必要性
非隔离的情况
当某一个服务接口处理能力减慢时,处理线程占用公共线程的时间就会较长,如果该接口的请求流量上升,就会造成整个服务的处理能力下降;
Hystrix线程池隔离
可以为每个接口(或者几个接口)设置单独的线程池,当该接口的线程池被占满时,只是该接口收到影响,而不会对其他接口造成影响;
Hystrix信号量隔离
可以为每个接口(或者几个接口)设置单独的信号量,当该接口的线程池被占满时,只是该接口收到影响,而不会对其他接口造成影响
线程池隔离与信号量隔离对比
信号量隔离
信号量是同步的,不能进行超时设置,当有大并发请求过来时,只有信号量大小的请求会进行真正的请求,其他的请求,只能fallback,而真正进行请求的线程,不能超时返回,只能等待服务端进行返回,结束本次请求,其他的线程才能再使用这个信号;
优点:轻量,没有线程上下文的切换;
- 优点:轻量,没有线程上下文的切换;
- 缺点:不能够设置超时时间;
- 使用场景:适合高并发,快速失败;以及不需要发送网络请求,只进行内存、缓存请求的场景;
线程池隔离
默认的隔离策略,这里每个请求会分成两段,一个是请求command,一个是执行command;也就是说执行请求的线程和请求线程(Tomcat线程)分离,请求线程可以自由控制离开的时间,即超时时间;
通过将发送请求线程与执行请求的线程分离,可有效防止发生级联故障。当线程池或请求队列饱和时,Hystrix将拒绝服务,使得请求线程可以快速失败,从而避免依赖问题扩散
- 优点:可以设置超时等;
- 缺点:增加了排队、调度和上下文切换的开销;
- 使用场景:适合高并发,快速失败;以及不需要发送网络请求,只进行内存、缓存请求的场景;
表格
线程切换 | 支持异步 | 支持超时 | 支持熔断 | 限流 | 开销 | |
---|---|---|---|---|---|---|
信号量 | 否 | 否 | 否 | 是 | 是 | 小 |
线程池 | 是 | 是 | 是 | 是 | 是 | 大 |
Hystrix优化配置
#配置熔断器Hystrix
hystrix:
threadpool:
default:
coreSize: 500
command:
default:
#熔断器属性配置,达到下面两个阈值才会熔断
circuitBreaker:
requestVolumeThreshold: 20 #默认滑动窗口时间内,请求量达到20次,进行熔断
errorThresholdPercentage: 50 #默认滑动窗口时间内,错误请求量达到百分之50,进行熔断
metrics:
rollingStats:
timeInMilliseconds: 10000 #默认滑动窗口时间10s
execution:
timeout:
enabled: true
isolation:
thread:
timeoutInMilliseconds: 10000 #请求时间达到的8s进行超时熔断
推荐阅读:
springCloud面试之feign+ribbon+hystirx交互概览
后记
如果不当之处欢迎指正~
更多推荐
springCloud面试之Hystrix
发布评论