【问题标题】:Hystrix Fallback method executionHystrix Fallback 方法执行
【发布时间】:2023-03-21 17:46:02
【问题描述】:

下面是我的Hystrix命令配置:

@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 个请求将在 10 秒内被允许,直到电路跳闸打开并且来自第 5 个请求的每个请求都将被拒绝,并且由于我在回退方法中抛出异常,它将被包装为 HystrixRuntimeException

但我面临以下问题:

  • 直到电路跳闸打开,故障恢复正常执行,并且 throwing CustomRuntimeException (注:Hystrix 命令方法也 抛出CustomRuntimeException)
  • 电路跳闸打开后,我得到Caused by: com.netflix.hystrix.exception.HystrixRuntimeException: getInfo short-circuited and fallback failed.

问题

  1. 为什么在电路打开之前异常没有被包装为 HystrixRuntimeException,即当前回退正常执行并抛出 CustomRuntimeException 直到电路打开?*

  1. 为什么在流程 1->2->3->4->5->6->8 甚至在 失败(即抛出CustomRuntimeException)并且不抛出 一个包裹的HystrixRuntimeException,这是在流的情况下发生的 1->2->3->4->8 和 1->2->3->5->8

【问题讨论】:

    标签: spring-boot hystrix circuit-breaker


    【解决方案1】:

    有关异常处理,请参阅 Hystrix Javanica 文档: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 断路器的配置添加到代码中。它们通常最好放在 spring 配置中,全名:hystrix.command.default.circuitBreaker.requestVolumeThreshold

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

    【讨论】:

    • 实际上我抛出了 2 个不同的异常;一个在命令方法中,另一个在后备方法中。从技术上讲,它应该只显示失败的根本原因,即 Command 方法抛出的异常;但就我而言,我得到的只是回退引发的异常。
    • 我已经用一个示例项目的链接更新了答案。在这个例子中,当断路器关闭时,我总是会收到主要异常,而当断路器打开时,我会收到 RuntimeException。
    • 抱歉耽搁了。测试用例在 Camden.SR7(hystrix 版本 1.5.6)中运行良好,但在 Dalston.SR3(hystrix 版本 1.5.12)中运行良好。版本更新后,它正在传播从回退方法抛出的异常。我认为错误隐藏回退异常后命令方法的传播是一个问题,已修复参考:github.com/Netflix/Hystrix/issues/332
    • 根据上面链接中提到的流程图,回退异常必须包装为 HystrixRuntimeException 但他没有发生。我已经在同一个项目上创建了一个项目,并且还提到了我作为 cmets 的问题。 github.com/chrysalisDVT/hystrix-example你能看一下吗?了解您对项目中的 cmets 的想法会有很大帮助。
    • 我在 1.5.7 的发行说明中看到行为发生了变化:“Javanica:向客户端发送回退异常而不是主命令。”。有一个指向拉取请求的链接,这个链接指向github.com/Netflix/Hystrix/issues/1344,最后有一些 cmets。默认情况下,Javanica(Spring 中的注解)不应该返回 HystrixRuntimeException。如果在没有 Spring 的情况下使用 HystrixRuntimeExceptions。我认为你在正确的轨道上 - 祝你好运!我退出了这个讨论。
    猜你喜欢
    • 2019-08-10
    • 2017-10-18
    • 2017-08-22
    • 2019-06-06
    • 2015-01-19
    • 2016-05-21
    • 1970-01-01
    • 2019-08-11
    • 1970-01-01
    相关资源
    最近更新 更多