Spring Bootアプリケーション内で_@HystrixCommand
_注釈を使用しているときにHystrixCommand
が失敗した理由を取得する方法はありますか?独自のHystrixCommand
を実装するとgetFailedExecutionException
にアクセスできるように見えますが、アノテーションを使用するときにこれにアクセスするにはどうすればよいですか?発生した例外の種類に基づいて、フォールバックメソッドで異なる処理を実行できるようにしたいと思います。これは可能ですか?
注 about HystrixRequestContext.initializeContext()
を見ましたが、HystrixRequestContext
は何にもアクセスできません。そのコンテキストを使用して、例外?
アノテーションで例外を取得する方法も見つけられませんでしたが、独自のコマンドを作成すると次のように機能しました:
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();
}
}
これが他の人にも役立つことを願っています。
フォールバックメソッドに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");
}
私は注釈で例外を取得する方法を見つけることができませんでしたが、HystrixPlugins
を見つけました。これにより、HystrixCommandExecutionHook
を登録でき、そのように正確な例外を取得できます:
HystrixPlugins.getInstance().registerCommandExecutionHook(new HystrixCommandExecutionHook() {
@Override
public <T> void onFallbackStart(final HystrixInvokable<T> commandInstance) {
}
});
コマンドインスタンスはGenericCommand
です。
ドキュメントで述べたように Hystrix-documentationgetFallback()
メソッドは次の場合にスローされます:
そのため、実行例外をThrowable objectに割り当てることで、フォールバックメソッドを呼び出したものを簡単に取得できます。
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
}
詳細 こちら
ほとんどの場合、単にgetFailedExecutionException()。getMessage()を使用すると、null値が返されます。
Exception errorFromThrowable = getExceptionFromThrowable(getExecutionException());
String errMessage = (errorFromThrowable != null) ? errorFromThrowable.getMessage()
これにより、常により良い結果が得られます。