转载:https://www.sczyh30.com/posts/Microservice/netflix-hystrix-how-it-works-summary/
这篇文章里我们来总结一下 Netflix Hystrix 的工作流程(版本为 1.4.x)。这是官方提供的流程图(来自 GitHub):
工作流程
我们来根据流程图来分析一下工作流程。
首先我们需要创建一个 HystrixCommand
或 HystrixObservableCommand
实例来代表向其它组件发出的操作请求(指令),然后通过相关的方法执行操作指令。这里有4个方法,前两个对应HystrixCommand
,后两个对应HystrixObservableCommand
:
execute()
:阻塞型方法,返回单个结果(或者抛出异常)queue()
:异步方法,返回一个Future
对象,可以从中取出单个结果(或者抛出异常)observe()
和toObservable()
都返回对应的Observable
对象,代表(多个)操作结果。注意observe
方法在调用的时候就开始执行对应的指令(hot observable 加了层 buffer 代理),而toObservable
方法相当于是observe
方法的lazy版本,当我们去subscribe
的时候,对应的指令才会被执行并产生结果
1
2
3
4
|
K value = command.execute();
Future<K> fValue = command.queue();
Observable<K> ohValue = command.observe();
//hot observable
Observable<K> ocValue = command.toObservable();
//cold observable
|
从底层实现来讲,HystrixCommand
也是利用Observable
实现的(看Hystrix源码的话可以发现里面大量使用了RxJava),尽管它只返回单个结果。HystrixCommand
的queue
方法实际上是调用了toObservable().toBlocking().toFuture()
,而execute
方法实际上是调用了queue().get()
。
执行操作指令时,Hystrix首先会检查缓存内是否有对应指令的结果,如果有的话,将缓存的结果直接以Observable
对象的形式返回。如果没有对应的缓存,Hystrix会检查Circuit Breaker的状态。如果Circuit Breaker的状态为开启状态,Hystrix将不会执行对应指令,而是直接进入失败处理状态(图中8 Fallback)。如果Circuit Breaker的状态为关闭状态,Hystrix会继续进行线程池、任务队列、信号量的检查(图中5),确认是否有足够的资源执行操作指令。如果资源满,Hystrix同样将不会执行对应指令并且直接进入失败处理状态。
如果资源充足,Hystrix将会执行操作指令。操作指令的调用最终都会到这两个方法:
HystrixCommand.run()
HystrixObservableCommand.construct()
如果执行指令的时间超时,执行线程会抛出TimeoutException
异常。Hystrix会抛弃结果并直接进入失败处理状态。如果执行指令成功,Hystrix会进行一系列的数据记录,然后返回执行的结果。
同时,Hystrix会根据记录的数据来计算失败比率,一旦失败比率达到某一阈值将自动开启Circuit Breaker。
最后我们再来看一下Hystrix是如何处理失败的。如果我们在Command中实现了HystrixCommand.getFallback()
方法(或HystrixObservableCommand.resumeWithFallback()
方法,Hystrix会返回对应方法的结果。如果没有实现这些方法的话,从底层看Hystrix将会返回一个空的Observable
对象,并且可以通过onError
来终止并处理错误。从上层看:
execute
方法将会抛出异常queue
方法将会返回一个失败状态的Future
对象observe()
和toObservable()
方法都会返回上述的Observable
对象