如何告诉Hystrix不要针对某些异常触发fallback在Hystrix命令中。

17

我们通过直接扩展HystrixCommand类来使用Hystrix功能。但是对于一些业务异常,会触发Hystrix的回退方法。

我不想针对某些业务特定异常触发Hystrix回退。我该如何在不使用注释的情况下实现?

3个回答

6
使用 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是通过构建器模式创建的,因此您需要进行一些修改。 ignoreExceptions添加到DefaultProperties.java中,该文件用于HystrixCommandBuilder。

根据我的理解,在HystrixCommandBuilder的ignoreexceptions方法内部,他只是在复制异常列表。但根据该方法的注释,我了解到这些被忽略的异常可以包装成Hystrixbadrequestexception。但您能否告诉我如何做,并提供一个更好的代码片段呢? - LazyGuy
只需在命令中设置该属性 - HystrixCommand 中没有这样的属性。 - Simon Forsberg

2
如果你将逻辑包裹在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

有两种方法来实现这个。

  1. Using HystrixCommand annotation and specifying the exception types.

    @HystrixCommand(ignoreExceptions = { HttpStatusCodeException.class, JsonMappingException.class })
    
  2. Using "HystrixBadRequestException" and customize your code in way to just ignore few exception cases or status codes. This implementation will check for specific error codes on exceptions expected with you backend API contract and does not invoke hystrix fallback. Throwing "HystrixBadRequestException" will not count as hystrix fault.

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接