目录
- 回退
- 异常传递
- 惊喜
Fallback(回退)
我们可以通过增加一个 fallback (回退)方法在hystrix命令实现优雅降级,如果主命令失败,hystrix可以获取一个默认值或者值集合。我们可能想为更多的可能失败的hrstrix命令实现一个回退方法,但是会有以下几种例外:
- 执行写操作的命令
如果设计的hrstrix命令是执行一个写操作而不是返回一个结果(这个写操作在 HystrixCommand
通常返回 void,在 HystrixObservableCommand
返回一个空的可观察者),此场景下执行回退方法没有什么意义,如果写操作失败,服务方应该是希望告知调用方,让调用方再进一步处理。
- 批处理系统/离线分析
如果Hystrix命令正在填充一个缓存,或者生成一个报告,或者做任何离线计算。如果发生错误,通常应该将错误告知调用方,让调用方做进一步处理,而不应该发送一个默认的响应。
如果命令执行异常,无论Hystrix命令是否有回退方法,hystrix命令状态、断路器/度量器都会更新为此条命令失败。
在一个普通的HystrixCommand
中通过重写 getFallback()
方法实现一个回退方法,比如 run()
方法有异常, hystrix会为所有类型的异常执行回退方法,比如 超时、线程池或信号量拒绝,以及断路器短路。 包含回退方法的示例如下:
public class CommandHelloFailure extends HystrixCommand<String> {
private final String name;
public CommandHelloFailure(String name) {
super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
this.name = name;
}
@Override
protected String run() {
throw new RuntimeException("this command always fails");
}
@Override
protected String getFallback() {
return "Hello Failure " + name + "!";
}
}
以上代码中 run()方法永远会出现异常,调用者永远接收到的是 getFallback()方法返回的值,不会接收到异常,以下单元测试成功:
@Test
public void testSynchronous() {
assertEquals("Hello Failure World!", new CommandHelloFailure("World").execute());
assertEquals("Hello Failure Bob!", new CommandHelloFailure("Bob").execute());
}
HystrixObservableCommand 等价方式
对于HystrixObservableCommand,需要通过重写 resumeWithFallback
方法,如果执行失败了,它就会从主观察者接管失败返回第二可观察者。这里需要注意的是,已经发送的一个或多个数据项之后,可观察者可能会失败,所以回退方法不应该假设它会发送观察者看到的唯一值。
在内部,Hystrix使用RxJava的 onerrorerrorenext操作符,在发生错误时,在主观察者和回退之间无缝切换。
时序图
@adrianb11 友好的提供了一个hystrix 超时回退时操作的时序图,点击查看
错误传播
从run()方法抛出的除 HystrixBadRequestException
异常外的所有异常,会统计异常次数、触发回退方法和短路逻辑。
可以将想抛出的异常包装到 HystrixBadRequestException
通过 getCause()
方法查询它 ,HystrixBadRequestException
适用于报告非法参数或非系统故障的场景,这些错误不应该与失败的指标相违背,也不应该触发回退逻辑。
HystrixObservableCommand 等价方式
在 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