咱们能够经过增长一个 fallback (回退)方法在hystrix命令实现优雅降级,若是主命令失败,hystrix能够获取一个默认值或者值集合。咱们可能想为更多的可能失败的hrstrix命令实现一个回退方法,可是会有如下几种例外:html
若是设计的hrstrix命令是执行一个写操做而不是返回一个结果(这个写操做在 HystrixCommand
一般返回 void,在 HystrixObservableCommand
返回一个空的可观察者),此场景下执行回退方法没有什么意义,若是写操做失败,服务方应该是但愿告知调用方,让调用方再进一步处理。java
若是Hystrix命令正在填充一个缓存,或者生成一个报告,或者作任何离线计算。若是发生错误,一般应该将错误告知调用方,让调用方作进一步处理,而不该该发送一个默认的响应。git
若是命令执行异常,不管Hystrix命令是否有回退方法,hystrix命令状态、断路器/度量器都会更新为此条命令失败。github
在一个普通的HystrixCommand
中经过重写 getFallback()
方法实现一个回退方法,好比 run()
方法有异常, hystrix会为全部类型的异常执行回退方法,好比 超时、线程池或信号量拒绝,以及断路器短路。 包含回退方法的示例以下:缓存
public class HystrixHelloWorldFallback extends HystrixCommand<String> { private final String name; public HystrixHelloWorldFallback(String name) { super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup")); this.name = name; } @Override protected String run() { throw new RuntimeException("模拟异常!"); } @Override protected String getFallback() { return "Hello Failure " + name + "!"; } }
以上代码中 run()方法永远会出现异常,调用者永远接收到的是 getFallback()方法返回的值,不会接收到异常,如下单元测试成功: 单元测试
@Test public void testSynchronous() { assertEquals("Hello Failure World!", new HystrixHelloWorldFallback("World").execute()); assertEquals("Hello Failure Bob!", new HystrixHelloWorldFallback("Bob").execute()); }
对于HystrixObservableCommand,须要经过重写 resumeWithFallback
方法,若是执行失败了,它就会从主观察者接管失败返回第二可观察者。这里须要注意的是,已经发送的一个或多个数据项以后,可观察者可能会失败,因此回退方法不该该假设它会发送观察者看到的惟一值。测试
在内部,Hystrix使用RxJava的 onerrorerrorenext操做符,在发生错误时,在主观察者和回退之间无缝切换。this
@adrianb11 友好的提供了一个hystrix 超时回退时操做的时序图,点击查看spa
从run()方法抛出的除 HystrixBadRequestException
异常外的全部异常,会统计异常次数、触发回退方法和短路逻辑。
能够将想抛出的异常包装到 HystrixBadRequestException
经过 getCause()
方法查询它 ,HystrixBadRequestException
适用于报告非法参数或非系统故障的场景,这些错误不该该与失败的指标相违背,也不该该触发回退逻辑。
在 HystrixObservableCommand
例子中,不可恢复的错误经过 产生 Observable
的 onError
通知, 而降低是经过回到第二个可观察到的,即Hystrix经过您实现的恢复的回退方法得到的, 降级是降低到经过 Hystrix实现 resumeWithFallback
方法得到的第二个可观察完成的。
失败类型 | 异常类 | 异常缘由 | 是否执行回退 |
---|---|---|---|
失败 | HystrixRuntimeException |
潜在异常(用户控制) | 执行 |
超时 | HystrixRuntimeException |
j.u.c.TimeoutException |
执行 |
短路 | HystrixRuntimeException |
j.l.RuntimeException |
执行 |
线程池异常 | HystrixRuntimeException |
j.u.c.RejectedExecutionException |
执行 |
信号量拒绝 | HystrixRuntimeException |
j.l.RuntimeException |
执行 |
失败请求 | HystrixBadRequestException |
underlying exception (user-controlled) | 不执行 |
转帖请注明原贴地址 : https://my.oschina.net/u/2342969/blog/1814990