Spring Cloud Hystrix 源码分析01

代码结构如下

Spring Cloud Hystrix 源码分析01

重点实现在hystrix-core 代码依赖下图所示

Spring Cloud Hystrix 源码分析01

先看一下核心接口HystrixInvokable,是一个空接口

Spring Cloud Hystrix 源码分析01

下面是子接口HystrixInvokableInfo,定义了一些接口方法

Spring Cloud Hystrix 源码分析01

直接看其具体实现类HystrixObservableCommand和HystrixCommand

HystrixCommand用在依赖服务返回单个操作结果的时候:

  • execute():同步执行。从依赖的服务返回一个单一的结果对象,或是在发生错误的时候抛出异常。
  • queue():异步执行。直接返回一个Future对象,其中包含了服务执行结束时要返回的单一结果对象。

HystrixObservableCommand用在依赖服务返回多个操作结果的时候:

observe():返回Obervable对象,他代表了操作的多个结果,它是一个Hot Observable
toObservable():同样返回Observable对象,也代表了操作多个结果,但它返回的是一个Cold Observable。

 

2.2 基本用法
有两种:手动自定义command和使用注解,手动自定义这里就不介绍了。这里介绍**解需要两步(对破析源码有用):

第一步:隐式模式(用户不需要做什么,但你要知道),spirng boot会自动加载Feign的配置类HystrixAutoConfiguration(spring-cloud-netflix-core-1.4.4.RELEASE.jar/META-INF/spring.factories)

第二步:应用系统启动类中添加@EnableHystrix,它的作用是将spring.cloud.circuit.breaker.enabled设为true。

Hystrix默认配置都在HystrixCommandProperties类中

 

HystrixCommand已具备了observe()和toObservable()的功能,和HystrixObservableCommand有和不同?

是的,但它的实现有一定的局限性,它返回的Observable只能发射一次数据,而HystrixObservableCommand实现的命令可以获取能发多次的Observable。

思考:多级降级的时候,为何将降级command单独做一个线程池?

如果主流程的command都失败了,可能线程池都已经被占满了,降级command必须用自己的独立的线程池。

3.1 构建命令
前面讲过Hystrix 提供了两个Command,可以使用这两个对象来包裹待执行的任务。 注解@HystrixCommand标记方法,Hystrix 将利用AOP自动将目标方法包装成HystrixCommand来执行,也可以继承他们来创建Command。任务委托给 Hystrix 后,Hystrix 可以应用自己的一系列保护机制,在执行用户任务的各节点(执行前、执行后、异常、超时等)做一系列的事情。

3.2 执行命令
有四种方式执行command:

R execute():同步执行,从依赖服务得到单一结果对象,实现为 queue().get()
Future queue():异步执行,返回一个 Future 以便获取执行结果,也是单一结果对象,实现为 toObservable().toBlocking().toFuture()
Observable observe():hot observable,创建Observable后会订阅Observable,可以返回多个结果
Observable toObservable():cold observable,返回一个Observable,只有订阅时才会执行,可以返回多个结果

3.3 检查缓存
    如果启用了 Hystrix Cache,任务执行前将先判断是否有相同命令执行的缓存。如果有则直接返回缓存的结果;如果没有缓存的结果,但启动了缓存,将缓存本次执行结果以供后续使用。

3.4 断路器是否打开
   断路器(circuit-breaker)和保险丝类似,保险丝在发生危险时将会烧断以保护电路,而断路器可以在达到我们设定的阀值时触发短路(比如请求失败率达到50%),拒绝执行任何请求。如果断路器被打开,Hystrix 将不会执行命令,直接进入Fallback处理逻辑。

3.5 检查线程池/信号量情况
   
Hystrix 隔离方式有线程池隔离和信号量隔离。当使用Hystrix线程池时,Hystrix 默认为每个依赖服务分配10个线程,当10个线程都繁忙时,将拒绝执行命令。信号量同理。

3.6 执行任务
通过HystrixObservableCommand.construct()或者 HystrixCommand.run() 来运行用户真正的任务。

3.7 断路器健康检查
每次开始执行command、结束执行command以及发生异常等情况时,都会记录执行情况,例如:成功、失败、拒绝以及超时等情况,会定期处理这些数据,再根据设定的条件来判断是否开启断路器。

3.8 失败时执行 Fallback
在命令失败时执行用户指定的 Fallback 逻辑。上图中的断路、线程池拒绝、信号量拒绝、执行执行、执行超时都会进入 Fallback 处理。

3.9 返回执行结果
原始结果将以Observable形式返回,在返回给用户之前,会根据调用方式的不同做一些处理。下面是 Hystrix Return flow

Spring Cloud Hystrix 源码分析01