Hystrix(2)流程介绍

下图显示了当我们通过 Hystrix 向服务依赖项发出请求时会发生什么:

以下部分将更详细地解释此流程:

1.构造一个HystrixCommand或HystrixObservableCommand对象

第一步是构造一个 HystrixCommand 或 HystrixObservableCommand 对象来表示我们对依赖项发出的请求。 向构造函数传递发出请求时需要的任何参数。

如果期望依赖项返回单个响应,则构造一个 HystrixCommand 对象。 例如:

HystrixCommand command = new HystrixCommand(arg1, arg2);

如果期望依赖项返回一个发出响应的 Observable,则构造一个 HystrixObservableCommand 对象。 例如:

HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);

2.执行Command

有四种方法可以执行命令,通过使用 Hystrix 命令对象的以下四种方法之一(前两种仅适用于简单的 HystrixCommand 对象,不适用于 HystrixObservableCommand):

  • execute() — 阻塞,然后返回从依赖项接收到的单个响应(或在发生错误时抛出异常)
  • queue() — 返回一个 Future,我们可以使用它从依赖项中获取单个响应
  • observe()  — 订阅表示来自依赖项的响应的 Observable,并返回一个复制该源 Observable 的 Observable
  • toObservable() — 返回一个 Observable,当我们订阅它时,它将执行 Hystrix 命令并发出它的响应
K             value   = command.execute();
Future<K>     fValue  = command.queue();
Observable<K> ohValue = command.observe();         //hot observable
Observable<K> ocValue = command.toObservable();    //cold observable

同步调用 execute() 就是调用 queue().get()。 queue() 就是依次调用toObservable().toBlocking().toFuture()。 也就是说,最终每个 HystrixCommand 都由 Observable 实现支持,即使是那些旨在返回单个简单值的命令。

3. 响应是否被缓存?

如果这个command开启了请求缓存,并且缓存中有请求的响应,那么这个缓存的响应会立即以 Observable 的形式返回。 (请参阅下面的“请求缓存”。)

4. Circuit是否Open?

当我们执行命令时,Hystrix 会检查断路器(circuit-breaker)以查看circuit是否打开。

如果circuit打开(或“跳闸”),则 Hystrix 不会执行command,但会将流程路由到 (8) Get the Fallback。

如果circuit闭合,则流程进行到 (5) 以检查是否有容量可用于运行命令。

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

如果与command关联的线程池和队列(或信号量,如果不在线程中运行)已满,则 Hystrix 不会执行命令,而是立即将流程路由到 (8) 获取 Fallback。

6. HystrixObservableCommand.construct() or HystrixCommand.run()

在这里,Hystrix 通过我们为此目的编写的方法调用对依赖项的请求,以下方法之一:

  • HystrixCommand.run() — 返回单个响应或抛出异常

  • HystrixObservableCommand.construct() — 返回一个 Observable 发出响应或发送 onError 通知

如果 run() 或construct() 方法超过命令的超时值,线程将抛出 TimeoutException (或者如果命令本身没有在自己的线程中运行,则单独的计时器线程将抛出)。 在这种情况下,Hystrix 将响应路由到 8.(获取 Fallback),如果该方法没有取消/中断,它会丢弃最终返回值 run() 或construct() 方法。

请注意,没有办法强制潜在线程停止工作——Hystrix 在 JVM 上可以做的最好的事情就是抛出一个 InterruptedException。 如果 Hystrix 包裹的工作不考虑 InterruptedExceptions,Hystrix 线程池中的线程将继续工作,尽管客户端已经收到了 TimeoutException。 这种行为可能会使 Hystrix 线程池饱和,尽管负载是“正确卸载”的。 大多数 Java HTTP 客户端库不解释 InterruptedExceptions。 因此,请确保在 HTTP 客户端上正确配置连接和读/写超时。

如果该command没有抛出任何异常并且它返回了响应,Hystrix 会在执行一些日志记录和指标报告后返回此响应。 在 run() 的情况下,Hystrix 返回一个 Observable,它发出单个响应,然后发出 onCompleted 通知; 在construct()的情况下,Hystrix返回construct()返回的相同的Observable。

7. 计算Circuit Health

Hystrix 向断路器(circuit breaker)报告成功、失败、拒绝和超时,断路器维护一组滚动的计数器来计算统计信息。

它使用这些统计数据来确定电路(circuit)何时应该“跳闸”,此时它会短路任何后续请求,直到经过恢复期,然后在首先检查某些健康检查后再次关闭电路。

8. Get the Fallback

每当command执行失败时,Hystrix 都会尝试恢复到我们的回退:当construct() 或run() (6.) 抛出异常时,当由于电路打开而导致命令短路时(4.),当 命令的线程池和队列或信号量达到容量 (5.),或者当命令超过其超时长度时。

编写哦我们呢的回退以从内存缓存或其他静态逻辑提供通用响应,而无需任何网络依赖。 如果我们必须在回退中使用网络调用,我们应该通过另一个 HystrixCommand 或 HystrixObservableCommand 这样做。

在 HystrixCommand 的情况下,要提供回退逻辑,我们需要实现 HystrixCommand.getFallback() ,它返回单个回退值。

在 HystrixObservableCommand 的情况下,要提供回退逻辑,我们需要实现 HystrixObservableCommand.resumeWithFallback() ,它返回一个可能发出一个或多个回退值的 Observable。

如果 fallback 方法返回一个响应,那么 Hystrix 将这个响应返回给调用者。 在 HystrixCommand.getFallback() 的情况下,它将返回一个 Observable,该 Observable 发出从该方法返回的值。 在 HystrixObservableCommand.resumeWithFallback() 的情况下,它将返回从该方法返回的相同 Observable。

如果我们没有为 Hystrix 命令实现回退方法,或者如果回退本身抛出异常,Hystrix 仍然返回一个 Observable,但它什么也不发出,并立即以 onError 通知终止。 正是通过这个 onError 通知,导致命令失败的异常被传回给调用者。 (实施可能失败的回退实现是一种糟糕的做法。我们应该实施回退,使其不执行任何可能失败的逻辑。)

失败或不存在的回退的结果将根据我们调用 Hystrix 命令的方式而有所不同:

  • execute() — 抛出异常
  • queue() — 成功返回一个 Future,但是如果调用它的 get() 方法,这个 Future 会抛出一个异常
  • observe() — 返回一个 Observable,当订阅它时,它会通过调用订阅者的 onError 方法立即终止
  • toObservable() — 返回一个 Observable,当订阅它时,它将通过调用订阅者的 onError 方法终止

9. Return the Successful Response

如果 Hystrix command成功,它将以 Observable 的形式向调用者返回一个或多个响应。 根据我们在上面第 2 步中调用命令的方式,此 Observable 可能会在返回给我们之前进行转换:

 

  • execute() — 以与 .queue() 相同的方式获取 Future,然后在此 Future 上调用 get() 以获取 Observable 发出的单个值
  • queue() — 将 Observable 转换为 BlockingObservable 以便可以将其转换为 Future,然后返回此 Future
  • observe() — 立即订阅 Observable 并开始执行命令的流程; 返回一个 Observable,当订阅它时,它会重放发射和通知
  • toObservable() — 返回 Observable 不变; 我们必须订阅它才能真正开始导致执行命令的流程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值