hystrix 插件使用 semaphore 的方式来处理请求,是 Soul 网关用来对流量进行熔断的核心实现。 借用官网的图,我们来理一下 Hystrix的流程:
- 每次调用创建一个HystrixCommand或一个HystrixObservableCommand对象,代表了对某个依赖服务发起的一次请求。
- HystrixCommand 主要用于仅仅会返回一个结果的调用。
- HystrixObservableCommand 主要用于可能会返回多条结果的调用。
-
- 执行execute()做同步调用或执行queue()做异步调用。
- 执行observe() 可以订阅一个Observable对象,Observable代表的是依赖服务返回的结果,获取到一个那个代表结果的Observable对象的副本。执行 toObservable() 会返回一个 Observable 对象,如果我们订阅这个对象,就会执行对应的 command 并且获取返回结果
- 如果这个 command 开启了请求缓存,并且request 和 response 在缓存中存在,则会立即从缓存中返回结果。
- 如果熔断器(circuit-breaker)是打开状态,则跳到步骤8,进行降级策略;如果关闭的话会进入步骤5。
- 判断线程池/信号量是否已经满了,如果跑满进入降级步骤8,否则继续后续步骤。
- 调用HystrixCommand.run() 或者 HystrixObservableCommand.construct():
- HystrixCommand.run():返回一个 response 或者 抛出一个异常。
- HystrixObservableCommand.construct():返回一个Observable对象,可以获取多条结果或发送一个onError通知
- 如果run() 或 construct() 调用超时,执行线程将抛出一个TimeoutException(如果命令本身不在自己的线程中运行,则单独的计时器线程将抛出一个TimeoutException)。此时执行步骤8调用 fallback 降级机制。run() 或 construct()方法的返回值也会被丢弃。
- 计算熔断器状态并所有的运行状态(成功,失败,拒绝,超时)上报给熔断器,用于统计从而判断熔断器状态。
- getFallback()降级逻辑.
- 以下四种情况将触发getFallback调用:
- 当construct()或run()方法抛出非 HystrixBadRequestException 异常。
- command执行超时
- 熔断器开启拦截调用
- 线程池/队列/信号量是否跑满
- 没有实现getFallback的Command将直接抛出异常
- fallback降级逻辑调用成功直接返回
- 降级逻辑调用失败抛出异常
- 以下四种情况将触发getFallback调用:
- 返回一个Observable对象,并根据第2步中执行的方法,转换需要的对象出来。
总结
hystrix 的运行流程实在是复杂,在下一节中我们会使用 soul 封装好的 hystrix 插件来做 熔断、降级。