接上一篇:《Hystrix介绍》html
下面这幅图至关重要git
稍微解释一下上面的流程:github
第一步是构造一个HystrixCommand或HystrixObservableCommand对象来表示对依赖项的请求。例如:缓存
HystrixCommand command = new HystrixCommand(arg1, arg2); HystrixObservableCommand command = new HystrixObservableCommand(arg1, arg2);
你能够用下列四种中的任意一种方式执行命令:并发
execute()方法是同步执行的,它是调用queue().get()异步
queue()方法是异步执行的,它调用的是toObservable().toBlocking().toFuture()性能
因此最终每一个HystrixCommand都是一个Observable的实现ui
若是请求在缓存中可用,而且该请求对应的响应在缓存中也是可用的,那么缓存的这个响应将当即以一个Observable的形式被返回spa
当你执行命令的时候,Hystrix检查断路器是不是开着的。若是是开着的,那么Hystrix不会执行命令,而是路由到第8步执行回退逻辑。若是是关着的,将执行第5步,继续检查容量是否可用。线程
若是这个命令所关联的线程池和队列(或者信号量)是否满了,若是是,那么Hystrix不会执行命令,而是当即路由到第8不执行回退逻辑
咱们知道对依赖的调用请求都是封装成HystrixCommand或者HystrixObservableCommand执行的,而真正执行的逻辑是写在HystrixObservableCommand.construct()或者HystrixCommand.run()中的:
若是在执行run()或者construct()方法超时,那么线程将抛出一个TimeoutException。
Hystrix报告成功、失败、拒绝、超时给断路器,断路器维护一组计算统计的计数器。
断路器用这些统计数据来决定何时应该“跳闸”,此时后续全部的请求都会被短路,直到一个恢复周期耗尽之后在第一次检查某些健康检查以后才会打开电路。
(PS:想象一下生活中的漏电保护器,电压太高时会自动跳闸,跳闸之后就没电了,家用电器都用不了了,以后你能够本身不去合上,固然前提是你不能再用那些大功率电器了,因而来电了)
当命令执行失败时,Hystrix试图恢复到您的fallback:当run()或者construct()抛出异常;当因为断路器跳闸致使命令被短路;当命令的线程池或队列容量满了;或者当命令执行超时。
在HystrixCommand的状况下,为了提供回退逻辑,你能够实现HystrixCommand.getfallback(),它返回一个单一的回退值。
对于HystrixObservableCommand(),为了提供回退逻辑,你须要实现hystrixobservablecomman.resumewithfallback(),它会返回一个Observable,这个Observable可能返回一个回退值或者多个值。
若是你没有实现一个fallback方法,或者fallback它本身抛了一个异常,此时Hystrix仍然会返回一个Observable,可是这个Observable什么都不会推送并当即发送一个onError通知。经过这个onError通知,形成命令失败的异常会传回给调用者。
若是Hystrix命令成功,它会返回响应给调用者,或者返回一个Observable。这取决于在第2步的时候你是若是调用命令的。
下图显示了HystrixCommand或HystrixObservableCommand是如何与HystrixCircuitBreaker交互的,以及它的逻辑和决策流程,包括断路器中计数器的行为。
上面的流程能够这样描述:
Hystrix使用隔板模式来隔离彼此的依赖关系,并限制对其中任何一个的并发访问。
Hystrix使用独立的、每一个依赖项的线程池做为约束任何给定依赖项的一种方式,所以底层执行的延迟只会使该池中的可用线程饱和。
你能够用信号量(或者计数器)来限制对任意依赖项并发调用的数量,代替用线程池的大小。
HystrixCommand 和 HystrixObservableCommand 在两个地方支持用信号量: