Hystrix工作原理一
运行时的流程图
-
构建
HystrixCommand
或者HystrixObservableCommand
对象第一步是构建一个HystrixCommand或HystrixObservableCommand对象来代表对依赖服务所做的请求。 将在请求发生时将需要的任何参数传递给构造函数。
如果依赖的服务预期会返回单一的响应, 构造一个
HystrixCommand
对象, 例如:HystrixCommand command = new HystrixCommand(arg1, arg2);
如果依赖的服务预期会返回一个发出响应的Observable对象, 则构造一个
HystrixObservableCommand
对象, 例如:HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
-
执行Command
-
响应是否被缓存?
如果Command的缓存请求被开启, 同时请求的响应在缓存中可用, 缓存的响应被立即以一个
Observable
的方式返回. -
断路器是否开启?
执行Command时, Hystrix会检查断路器(circuti-breaker)是否开始回路(circuit).
如果回路开启, Hystrix将不会执行Command, 而直接去到流程8: Get the Fallback 如果关闭, 则执行流程5检查是否有足够的容量来运行该命令
-
线程池/队列/限号量是否满?
假如与Command相关的线程池和队列(或者信号量, 不适用隔离线程的话)满了, Hystrix将不会执行Command, 而是直接去到流程8.
-
HystrixObservableCommand.construct()
或HystrixCommand.run()
Hystrix使用下面任一的方式向依赖的服务发出请求:
HystrixCommand.run()
返回单个响应或抛出异常HystrixObservableCommand.construct()
返回一个发出响应的Observable对象, 或者发送onError
通知
如果
run()
或者construct()
方法执行超过Command的超时设置, 线程会抛出一个TimeoutException
(或者独立的timer线程抛出, 如果Command不是运行在它自己的线程上). 这是Hystrix直接去到流程8. 获取Fallback
, 如果没有cancel/interrup, 则抛弃run()
或construct()
的最终返回值.请注意, 没有任何方法可以强制任务线程停止工作, 最佳的方式是Hystrix抛出一个
InterruptException
. 如果Hystrix封装的任务忽略InterruptException
, 该任务线程会继续工作, 即使客户端已经收到了一个TimeoutException
. 这种行为会是Hystrix的线程池饱和, 尽管负载正确地流出(correctly shed)
. 大多数Java HTTP客户端库不解释InterruptedExceptions. 因此, 请确保在HTTP客户端上正确配置连接和读/写超时.如果Command执行没有超时而返回一个响应, Hystrix在执行某些日志记录和指标报告之后返回这个响应.
-
计算电路健康
Hystrix将成功, 失败, 拒绝服务和超时上报给断路器, 断路器维护着一个计算统计数据的计数器.
它通过这些统计数据决定断路器何时应该打开, 在哪个点开始短路后续的请求知道恢复期过去, 或者决定在第一次健康检查请求结束后是否要关闭断路器.
-
获取
Fallback
在command执行失败后: 当
run()
或construct()
抛出异常(6), command因为断路器开启而短路(4), command的线程池和队列或者计数器处于满负荷(6), 或者执行超时, Hystrix尝试转向你的Fallback
. -
返回成功的响应
如果Command处理成功, 它将以
Obervable
的实行返回response或者responses给调用者. 取决于上面流程2中的Command的执行方式, 该Observable
可能在返回给你之前被转换:- execute() - 返回一个
Fature
对象, 可以通过调用get()
获取Obervable
返回的单个值 - queue() - 把
Observable
转换为BlockingObservable
, 因此BlockingObservable
可以被转换成Future
, 并返回 - observe() - 理解订阅
Observable
, 并开始Command的执行流程. 返回一个Observable
, 当订阅它时, 重播返回和通知(replay emissions and notifiactions). - toObservable() - 不变地返回Observable; 必须订阅它才能真正开始导致执行命令的流程.
- execute() - 返回一个
断路器
- 假设通过断路器的负载达到了阈值 (HystrixCommandProperties.circuitBreakerRequestVolumeThreshold())
- 假设错误百分比超过错误的阈值 (HystrixCommandProperties.circuitBreakerErrorThresholdPercentage())
- 断路器状态从关闭变为打开
- 打开后, 断路器会短路所有针对该断路器的请求
- 过了一段时间后(HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds()), 下一条请求会被放行(半开状态). 如果请求失败, 断路器重回打开状态(OPEN)并持续一个睡眠窗口(sleep window). 如果成功, 状态变为关闭(CLOSED). 下个请求从逻辑1开始.