web-dev-qa-db-ja.com

How to say HystrixはHystrixコマンドの一部の例外のフォールバックをトリガーしないようにする

HystrixCommandクラスを直接拡張して、Hystrix機能を使用していました。ただし、一部のビジネス例外では、Hystrixのフォールバックメソッドがトリガーされています。

ビジネス固有の例外の一部について、Hystrixフォールバックをトリガーしたくありません。どのようにしてアノテーションベースなしでそれを達成できますか?

11
LazyGuy

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に追加されました。

1
sercasti

これを行うには2つの方法があります。

  1. HystrixCommandアノテーションを使用し、例外タイプを指定します。

    @HystrixCommand(ignoreExceptions = { HttpStatusCodeException.class, JsonMappingException.class })
    
  2. 「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);
        }
    
1
Achu22

ロジックを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);
    }
}

ドキュメントから: http://netflix.github.io/Hystrix/javadoc/com/netflix/hystrix/exception/HystrixBadRequestException.html

実行の失敗ではなく、指定された引数または状態のエラーを表す例外。 HystrixCommandによってスローされる他のすべての例外とは異なり、これはフォールバックをトリガーせず、障害メトリックにカウントされず、したがって回路ブレーカーをトリガーしません。

注:これは、エラーがIllegalArgumentExceptionなどのユーザー入力によるものである場合にのみ使用してください。それ以外の場合は、フォールトトレランスとフォールバック動作の目的に反します。

1
devo