什么是Hystrix

Hystrix是一个通过资源隔离实现服务熔断降级的中间件

Hystrix的作用

  1. 熔断
  2. 降级

Hystrix原理

处理流程,我下面的贴图来自GitHub:流程图


这里我又画了一个简化版如下图

流程解释:

  1. 构造一个 HystrixCommand或HystrixObservableCommand对象,用于封装请求,并在构造方法配置请求被执行需要的参数;
  2. 执行命令,Hystrix提供了4种执行命令的方法,后面详述;
  3. 判断是否使用缓存响应请求,若启用了缓存,且缓存可用,直接使用缓存响应请求。Hystrix支持请求缓存,但需要用户自定义启动;
  4. 判断熔断器是否打开,如果打开,跳到第8步;
  5. 判断线程池/队列/信号量是否已满,已满则跳到第8步;
  6. 执行HystrixObservableCommand.construct()或HystrixCommand.run(),如果执行失败或者超时,跳到第8步;否则,跳到第9步;
  7. 统计熔断器监控指标;这里至少需要知道两个指标,只有这两个指标同时达到阈值的时候,才会发生熔断
    • 滚动窗口时间内请求量
    • 滚动窗口时间内发生错误的请求量
  8. 走Fallback备用逻辑
  9. 返回请求响应

资源隔离

通过三个角度讲一下资源隔离的必要性

非隔离的情况

当某一个服务接口处理能力减慢时,处理线程占用公共线程的时间就会较长,如果该接口的请求流量上升,就会造成整个服务的处理能力下降;

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