Hystrix的应用

这一小节将会比13.2节介绍得更加深入一些,然后讲解在程序中如何使用自定义容错功能。

Hystrix工作流程

图13.15所示为 Hystrix 工作流程。这里只展示了一部分,具体可以去 GitHub 官网上查看。

image 2024 04 01 12 13 51 606
Figure 1. 图13.15 Hystrix工作流程

下面将通过图13.15介绍使用 Hystrix 的依赖请求如何工作。

构建对象

首先构建一个对象,可以是 HystrixCommand 或 HystrixObserverCommand 核心代理,对象只需要继承就可以了,这个对象代表一个依赖请求,负责向构造函数中传入依赖所需要的参数。

使用 HystrixCommand。只能向调用程序发送单条数据,依赖将会返回单个响应。这个逻辑命令写在 run 方法中,并在新创建的线程中执行。

使用 HystrixObservableCommand。逻辑命令写在 construct 中,并在调用程序的线程中执行,相对于前者,这里的一个实例可以顺序发送多条数据。

执行命令

在上图中可以发现,有四种方式可以执行 Hystrix 命令,但具体的调用路线没画,可以参看官网原图。

  • execute:在调用 #queue 方法的基础上,调用 Future#get 方法,同步返回 #run 的执行结果。

  • queue:在调用 #toObservable 方法的基础上,调用 Observable#toBlocking 和 BlockingObservable#toFuture 返回 Future 对象。

  • observe:调用 #toObservable 方法,并向 Observable 注册发起订阅。

  • toObservable:未做订阅,只是返回一个 Observable。

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 都是通过 to Observable 来实现的。

响应是否缓存

在图中,我们可以发现如果缓存开启,则请求的响应去缓存中获取。

回路器是否打开

当命令执行到回路器时,Hystrix 会检查回路器是否打开。如果回路器打开,那么 Hystrix 就不会再执行命令,而是直接路由获取 getFallback 方法,并执行 fallback 逻辑。

如果回路器关闭,那么检查是否有足够的容量来执行任务。如果没有,则进入 fallback 逻辑,如果有,则继续执行 Construct 或者 run 逻辑。

总结

首先,每个请求调用创建一个 HystrixCommand 对象,把依赖调用封装在 run 中。然后,执行 execute 或 queue 方法进行同步或者异步调用。然后,判断熔断器状态,如果打开,则进行降级策略。否则,程序正常执行。最后,判断线程池或队列或信号量是否跑满,如果跑满进行降级。

调用 HystrixCommand 的 run 方法运行依赖逻辑,如果依赖逻辑调用超时,则降级;判断逻辑是否调用成功,如果是则返回成功调用结果,否则降级;计算熔断器状态,所有的运行状态上报给熔断器,用于统计从而判断熔断器状态。

自定义使用Hystrix

Hystrix 是 Netfix 的一个开源容错系统,开发人员可以使用它处理容错性的程序,只需要继承 HystrixCommand 或者 HystrixObservableCommand,然后调用里面的 run 或者 construct 方法,最后,调用程序初始化,并执行四个方法即可。

目前的演示程序写在服务消费者应用中,暂时不需要考虑启动服务注册中心或者服务提供者的应用,所以可以使用测试类进行测试。程序结构图如图13.16所示。

image 2024 04 01 12 19 23 885
Figure 2. 图13.16 程序结构

根据图13.16的程序结构,我们只要写两段程序就可以进行验证了。新建一个 hystrix 包用于存放 Hystrix 的逻辑程序,然后使用测试类 TestHystrix 进行测试。HelloHystrixCommand 代码如下所示。

package com.cloudtest.eurekaconsumer.hystrix;
public class HelloHystrixCommand extends HystrixCommand {
   private final String name;
   public HelloHystrixCommand(String name) {
      super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
      this.name = name;
   }
   @Override
   protected String run() {
      return "Hello " + name;
   }
}

测试类的代码如下所示。

package com.cloudtest.eurekaconsumer;
public class TestHystrix {
   @Test
   public void test(){
      String result = new HelloHystrixCommand("CJ").execute(). toString();
      System.out.println(result);
   }
}

然后进行测试,执行结果如图13.17所示。

image 2024 04 01 12 20 54 939
Figure 3. 图13.17 执行结果