运行时的流程图

图片来自netflix hystrix

  1. 构建HystrixCommand或者HystrixObservableCommand对象

    第一步是构建一个HystrixCommand或HystrixObservableCommand对象来代表对依赖服务所做的请求。 将在请求发生时将需要的任何参数传递给构造函数。

    如果依赖的服务预期会返回单一的响应, 构造一个HystrixCommand对象, 例如:

    1
    HystrixCommand command = new HystrixCommand(arg1, arg2);

    如果依赖的服务预期会返回一个发出响应的Observable对象, 则构造一个HystrixObservableCommand对象, 例如:

    1
    HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
  2. 执行Command

  3. 响应是否被缓存?

    如果Command的缓存请求被开启, 同时请求的响应在缓存中可用, 缓存的响应被立即以一个Observable的方式返回.

  4. 断路器是否开启?

    执行Command时, Hystrix会检查断路器(circuti-breaker)是否开始回路(circuit).

    如果回路开启, Hystrix将不会执行Command, 而直接去到流程8: Get the Fallback
    如果关闭, 则执行流程5检查是否有足够的容量来运行该命令

  5. 线程池/队列/限号量是否满?

    假如与Command相关的线程池和队列(或者信号量, 不适用隔离线程的话)满了, Hystrix将不会执行Command, 而是直接去到流程8.

  6. 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在执行某些日志记录和指标报告之后返回这个响应.

  7. 计算电路健康

    Hystrix将成功, 失败, 拒绝服务和超时上报给断路器, 断路器维护着一个计算统计数据的计数器.

    它通过这些统计数据决定断路器何时应该打开, 在哪个点开始短路后续的请求知道恢复期过去, 或者决定在第一次健康检查请求结束后是否要关闭断路器.

  8. 获取Fallback

    在command执行失败后: 当run()construct()抛出异常(6), command因为断路器开启而短路(4), command的线程池和队列或者计数器处于满负荷(6), 或者执行超时, Hystrix尝试转向你的Fallback.

  9. 返回成功的响应

    如果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; 必须订阅它才能真正开始导致执行命令的流程.

      更详细的流程图

断路器

  1. 假设通过断路器的负载达到了阈值 (HystrixCommandProperties.circuitBreakerRequestVolumeThreshold())
  2. 假设错误百分比超过错误的阈值 (HystrixCommandProperties.circuitBreakerErrorThresholdPercentage())
  3. 断路器状态从关闭变为打开
  4. 打开后, 断路器会短路所有针对该断路器的请求
  5. 过了一段时间后(HystrixCommandProperties.circuitBreakerSleepWindowInMilliseconds()), 下一条请求会被放行(半开状态). 如果请求失败, 断路器重回打开状态(OPEN)并持续一个睡眠窗口(sleep window). 如果成功, 状态变为关闭(CLOSED). 下个请求从逻辑1开始.

翻译自Hystrix Wiki - How it works