【问题标题】:How to say Hystrix not to trigger fallback for some of the exceptions in Hystrix command如何说 Hystrix 不会为 Hystrix 命令中的某些异常触发回退
【发布时间】:2017-10-30 00:47:45
【问题描述】:

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

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

【问题讨论】:

    标签: java hystrix netflix


    【解决方案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 命令是由 Builder 模式创建的,因此您必须进行一些黑客操作。在 HystrixCommandBuilder 中使用的 DefaultProperties.java 中添加了 ignoreExceptions

    【讨论】:

    • 据我了解。在 HystrixCommandBuilder 的 ignoreexceptions 方法中,他只是在复制异常列表。但是根据方法注释,我了解到这些被忽略的异常可以包含在 Hystrixbadrequestexception 中。但是你能告诉我如何做到这一点,并以更好的方式使用代码 sn-p
    • “只需在命令中设置该属性”-HystrixCommand 中没有此类属性
    【解决方案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)引起时使用,否则它会破坏容错和回退行为的目的。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 2017-03-22
        • 2018-07-15
        • 2022-01-13
        • 2017-10-10
        • 2020-08-08
        • 2018-05-16
        • 2018-08-01
        • 2018-04-05
        • 2021-01-31
        相关资源
        最近更新 更多