在@HystrixCommand回退方法

时间:2015-09-28 19:49:07

标签: spring spring-cloud hystrix

在Spring Boot应用程序中使用HystrixCommand注释时,是否有办法解决@HystrixCommand失败的原因?看起来如果您实现自己的HystrixCommand,您可以访问getFailedExecutionException,但在使用注释时如何才能访问此权限?我希望能够根据发生的异常类型在回退方法中执行不同的操作。这可能吗?

我看到关于HystrixRequestContext.initializeContext()的{​​{3}},但HystrixRequestContext没有授予您访问任何内容的权限,是否有不同的方式来使用该上下文来访问异常?

5 个答案:

答案 0 :(得分:44)

只需在fallback方法中添加一个Throwable参数,它就会收到原始命令产生的异常。

来自https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica

    @HystrixCommand(fallbackMethod = "fallback1")
    User getUserById(String id) {
        throw new RuntimeException("getUserById command failed");
    }

    @HystrixCommand(fallbackMethod = "fallback2")
    User fallback1(String id, Throwable e) {
        assert "getUserById command failed".equals(e.getMessage());
        throw new RuntimeException("fallback1 failed");
    }

答案 1 :(得分:11)

我还没有找到使用Annotations获取异常的方法,但创建我自己的Command对我来说是这样的:

public static class DemoCommand extends HystrixCommand<String> {

    protected DemoCommand() {
        super(HystrixCommandGroupKey.Factory.asKey("Demo"));
    }

    @Override
    protected String run() throws Exception {
        throw new RuntimeException("failed!");
    }

    @Override
    protected String getFallback() {
        System.out.println("Events (so far) in Fallback: " + getExecutionEvents());
        return getFailedExecutionException().getMessage();
    }

}

希望这对其他人也有帮助。

答案 2 :(得分:2)

我找不到使用注释获取异常的方法,但我发现HystrixPlugins,你可以注册一个HystrixCommandExecutionHook,你就可以得到这样的确切异常:

HystrixPlugins.getInstance().registerCommandExecutionHook(new HystrixCommandExecutionHook() {
            @Override
            public <T> void onFallbackStart(final HystrixInvokable<T> commandInstance) {

            }
        });

命令实例是GenericCommand

答案 3 :(得分:1)

大多数时候只使用getFailedExecutionException()。getMessage()给了我空值。

   Exception errorFromThrowable = getExceptionFromThrowable(getExecutionException());
   String errMessage = (errorFromThrowable != null) ? errorFromThrowable.getMessage()

这给了我更好的结果。

答案 4 :(得分:1)

如文档中所述,Hystrix-documentation getFallback()方法将在以下情况下抛出:

  1. 每当命令执行失败:construct()或run()引发异常时
  2. 由于电路开路而导致命令短路
  3. 当命令的线程池和队列或信号量达到容量时
  4. 命令超过其超时长度时。

因此,您可以通过将执行异常分配给 Throwable对象,轻松获得引发后备方法调用的方法。

假设您的HystrixCommand返回一个字符串

public class ExampleTask extends HystrixCommand<String> {
   //Your class body
}

执行以下操作:

@Override
    protected ErrorCodes getFallback() {
        Throwable t = getExecutionException();
        if (circuitBreaker.isOpen()) {
            // Log or something
        } else if (t instanceof RejectedExecutionException) {
            // Log and get the threadpool name, could be useful
        } else {
            // Maybe something else happened
        }
        return "A default String"; // Avoid using any HTTP request or ypu will need to wrap it also in HystrixCommand
    }

更多信息here