怎么说hystrix不会触发hystrix命令中的一些例外的回退

时间:2017-05-29 16:37:54

标签: java hystrix netflix

我们通过直接扩展HystrixCommand类来使用hystrix功能。 但是对于一些业务异常,正在触发hystrix的后备方法。

我不想触发某些业务特定异常的hystrix回退。如何在没有基于注释的情况下实现它?

先谢谢..!

3 个答案:

答案 0 :(得分:1)

使用ignoreExceptions注释参数

@HystrixCommand(ignoreExceptions = { BaseException.class, MissingServletRequestParameterException.class, TypeMismatchException.class })

请参阅https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#error-propagation

我看到你正在扩展HystrixCommand而不是使用注释,但这没关系,只需在命令中设置该属性,它应该具有相同的效果。

不幸的是,Hystrix Command是由Builder模式创建的,所以你必须做一些黑客攻击。 ignoreExceptions被添加到DefaultProperties.java,它在HystrixCommandBuilder中使用

答案 1 :(得分:1)

如果您将逻辑包装在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,否则会破坏容错和回退行为的目的。

答案 2 :(得分:0)

两种方法可以做到这一点。

  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);
        }