HystrixCommandクラスを直接拡張して、Hystrix機能を使用していました。ただし、一部のビジネス例外では、Hystrixのフォールバックメソッドがトリガーされています。
ビジネス固有の例外の一部について、Hystrixフォールバックをトリガーしたくありません。どのようにしてアノテーションベースなしでそれを達成できますか?
IgnoreExceptionsアノテーションパラメータを使用する
@HystrixCommand(ignoreExceptions = { BaseException.class, MissingServletRequestParameterException.class, TypeMismatchException.class })
https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#error-propagation を参照してください
アノテーションを使用する代わりにHystrixCommandを拡張しているようですが、それは問題ではありません。コマンドでそのプロパティを設定するだけで、同じ効果が得られます。
残念ながら、Hystrixコマンドはビルダーパターンによって作成されるため、ハッキングを行う必要があります。 ignoreExceptionsが、HystrixCommandBuilderで使用されるDefaultProperties.Javaに追加されました。
これを行うには2つの方法があります。
HystrixCommandアノテーションを使用し、例外タイプを指定します。
@HystrixCommand(ignoreExceptions = { HttpStatusCodeException.class, JsonMappingException.class })
「HystrixBadRequestException」を使用して、いくつかの例外ケースまたはステータスコードを無視するようにコードをカスタマイズします。この実装は、バックエンドAPIコントラクトで予期される例外の特定のエラーコードをチェックし、hystrixフォールバックを呼び出しません。 "HystrixBadRequestException"をスローすると、hystrix障害としてカウントされません。
@HystrixCommand(commandKey = "MyHystrixCommand", fallbackMethod = "myHystrixFallback", threadPoolKey = "ThreadPoolKey")
public ResponseEntity<String> getServiceCallResponse(String serviceUrl, HttpEntity<?> entity) {
ResponseEntity<String> resp = null;
try {
resp = restTemplate.exchange(serviceUrl, HttpMethod.POST, entity, String.class)
.getBody();
}
catch(Exception e) {
handleExceptionForHystrix("getServiceCallResponse", e);
}
return resp;
}
private void handleExceptionForHystrix(String function, Exception e) {
if (e instanceof HttpStatusCodeException) {
HttpStatus httpStatusCode = ((HttpStatusCodeException)e).getStatusCode();
if(httpStatusCode.equals(HttpStatus.BAD_REQUEST) || httpStatusCode.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
throw new HystrixBadRequestException("Hystrix Bad Request Exception Occurred" + httpStatusCode, e);
}
throw new RuntimeException(function, e);
}
throw new RuntimeException(function, e);
}
public ResponseEntity<String> myHystrixFallback(String serviceUrl, HttpEntity<?> entity, Throwable hystrixCommandExp) {
return new ResponseEntity<String>(HttpStatus.INTERNAL_SERVER_ERROR);
}
ロジックをtry/catchでラップし、HystrixBadRequestExceptionで例外を再スローすると、フォールバックはトリガーされません。
@Override
protected Object run() throws Exception {
try {
return //call goes here
}
catch (Throwable e) {
//We wrap any exceptions in a HystrixBadRequestException because this way any other errors will not
//trip the short circuit
throw new HystrixBadRequestException("Exception thrown hystrix call", e);
}
}
実行の失敗ではなく、指定された引数または状態のエラーを表す例外。 HystrixCommandによってスローされる他のすべての例外とは異なり、これはフォールバックをトリガーせず、障害メトリックにカウントされず、したがって回路ブレーカーをトリガーしません。
注:これは、エラーがIllegalArgumentExceptionなどのユーザー入力によるものである場合にのみ使用してください。それ以外の場合は、フォールトトレランスとフォールバック動作の目的に反します。