工作流程图
下面的流程图展示了当使用Hystrix的依赖请求,Hystrix是如何工作的。
下面将更详细的解析每一个步骤都发生哪些动作:
构建一个HystrixCommand或者HystrixObservableCommand对象。
第一步就是构建一个HystrixCommand或者HystrixObservableCommand对象,该对象将代表你的一个依赖请求,向构造函数中传入请求依赖所需要的参数。
如果构建HystrixCommand中的依赖返回单个响应,例如:
HystrixCommand command = new HystrixCommand(arg1, arg2);
如果依赖需要返回一个Observable来发射响应,就需要通过构建HystrixObservableCommand对象来完 成,例如:
HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
执行命令
有4种方式可以执行一个Hystrix命令。
execute()—该方法是阻塞的,从依赖请求中接收到单个响应(或者出错时抛出异常)。
queue()—从依赖请求中返回一个包含单个响应的Future对象。
observe()—订阅一个从依赖请求中返回的代表响应的Observable对象。
toObservable()—返回一个Observable对象,只有当你订阅它时,它才会执行Hystrix命令并发射响应。
K value = command.execute();
Future fValue = command.queue();
Observable ohValue = command.observe(); //hot observable
Observable ocValue = command.toObservable(); //cold observable
同步调用方法execute()实际上就是调用queue().get()方法,queue()方法的调用的是toObservable().toBlocking().toFuture().也就是说,最终每一个HystrixCommand都是通过Observable来实现的,即使这些命令仅仅是返回一个简单的单个值。
响应是否被缓存
如果这个命令的请求缓存已经开启,并且本次请求的响应已经存在于缓存中,那么就会立即返回一个包含缓存响应的Observable(下面将Request Cache部分将对请求的cache做讲解)。
回路器是否打开
当命令执行执行时,Hystrix会检查回路器是否被打开。
如果回路器被打开(或者tripped),那么Hystrix就不会再执行命名,而是直接路由到第8步,获取fallback方法,并执行fallback逻辑。
如果回路器关闭,那么将进入第5步,检查是否有足够的容量来执行任务。(其中容量包括线程池的容量,队列的容量等等)。
线程池、队列、信号量是否已满
如果与该命令相关的线程池或者队列已经满了,那么Hystrix就不会再执行命令,而是立即跳到第8步,执行fallback逻辑。
HystrixObservableCommand.construct() 或者 HystrixCommand.run()
在这里,Hystrix通过你写的方法逻辑来调用对依赖的请求,通过下列之一的调用:
HystrixCommand.run()—返回单个响应或者抛出异常。
HystrixObservableCommand.construct()—返回一个发射响应的Observable或者发送一个onError()的通知。
如果执行run()方法或者construct()方法的执行时间大于命令所设置的超时时间值,那么该线程将会抛出一个TimeoutException异常(或者如果该命令没有运行在它自己的线程中,[or a separate timer thread will, if the