2017-08-31 48 views
0

下面是我猬命令配置:猬回退方法执行

@HystrixCommand(fallbackMethod = "fall", commandProperties = { 
      @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"), 
      @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000") }) 
    public <T> T getInfo(Class clazz) {....} 

回退方法:

public <T> T fall(Class clazz) { 
     System.out.println("fallback"); 
     throw new CustomRuntimeException("API Down"); 
    } 

据我所知,按照下面的配置即

@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "5"), 
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds", value = "10000") } 

5请求将在10s内允许,直到电路开路并且来自第5个请求的每个请求都将被拒绝d,因为我在后备方法中抛出异常,所以它会被封装为HystrixRuntimeException

但我面临以下问题:

  • 直到电路跳闸打开后退时被正常执行,但 投掷CustomRuntimeException(注:猬命令方法也 抛出CustomRuntimeException
  • 后的电路跳闸开放我越来越Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: getInfo short-circuited and fallback failed.

问题

  1. 为什么电路之前的异常没有包装为HystrixRuntimeException是开放的,即目前的回落是正常执行,直到电路变得开放抛出CustomRuntimeException?*

How Hystrix works

  • 为什么在流程1-> 2-> 3-> 4-> 5-> 6-> 8中,即使在 失败后仍执行回退方法投掷CustomRuntimeException)并且不抛出 包裹的HystrixRuntimeException,这发生在流程 1-> 2-> 3-> 4-> 8并且1-> 2-> 3-> 5-> 8
  • 回答

    2

    请参阅有关的异常处理猬鸦胆子文档:https://github.com/Netflix/Hystrix/tree/master/hystrix-contrib/hystrix-javanica#error-propagation

    从文档报价:

    “值得注意的是,默认情况下来电者总是会得到根本原因异常.. 。从不HystrixBadRequestException或HystrixRuntimeException“

    “如果命令有回退,则只有第一个触发备用逻辑的异常将传播给调用者。”

    这两个引号回答你的第一个问题:第一个方法的异常将抛出异常,而不是HystrixRuntimeException。在回退中引发的异常将永远不会显示。

    断路器断开时,会引发RuntimeException。同样,在回退中抛出的异常将永远不会显示。

    我写这个测试用例:https://github.com/ahus1/hystrix-spring-examples/blob/master/src/test/java/de/ahus1/hystrixspring/HystrixExceptionHandlingInSpring.java

    旁注:

    1. 您添加的配置为您cicruit断路器的代码。它们通常更好地放置在弹簧配置中,其全名为:hystrix.command.default.circuitBreaker.requestVolumeThreshold

    2. requestVolumeThreshold与您所描述的有点不同:它定义了允许触发cicruit断路器之前在一个时间窗口中所需的最小请求数。 errorThresholdPercentage是一旦请求的最小数量(在你的情况下为5)所允许的错误的百分比。在你的情况下,5个呼叫中有5个失败,即100%。 100%大于50%(断路器的默认值),因此它打开。

    +1

    其实我分别抛出了两个不同的异常:一个在命令方法和另一个在回退方法。从技术上讲,它应该只显示失败的根本原因,即由Command方法引发的异常;但在我的情况下,我只得到了后备抛出的异常。 –

    +1

    我已经用示例项目的链接更新了答案。在这个例子中,当断路器闭合时,我总是收到主要异常,断路器断开时会收到RuntimeException。 – ahus1

    +1

    延误道歉。 测试用例与Camden.SR7(hystrix版本1.5.6)一起工作正常,但不在Dalston.SR3(hystrix版本1.5.12)。版本更新后,它正在传播从fallback方法抛出的异常。我认为在隐藏回退异常之后,命令方法的错误传播是一个问题,并且是固定引用:https://github.com/Netflix/Hystrix/issues/332。 –