繁体   English   中英

Spring Cloud Feign 客户端,带 Hystrix 断路器超时默认为 2 秒

[英]Spring Cloud Feign client with Hystrix circuit-breaker timeout defaults in 2 seconds

可通过 GitHub 上的项目重现: spring-cloud-feign-hystrix-timeout-problem


我正在使用 Spring Boot 2.3.1.RELEASE和 Spring Cloud Hoxton.SR6 即没有 Zuul 和 Eureka 的 Feign 客户端和 Hystrix 来获取 REST 响应。

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-dependencies</artifactId>
   <version>Hoxton.SR6</version>
   <type>pom</type>
   <scope>import</scope>
</dependency>

然后我在 Spring Boot 2.3.1.RELEASESpring Cloud Hoxton.SR6之上使用以下依赖项:

  • org.springframework.bootspring-boot-starter
  • org.springframework.bootspring-boot-starter-web
  • org.springframework.cloud spring-cloud-starter-openfeign
  • org.springframework.cloud spring-cloud-starter-netflix-hystrix

我启用@EnableFeignClients@EnableCircuitBreaker并使用带有简单后备的@FeignClient来记录并重新抛出异常:

@FeignClient(name="my-feign", url = "${feign.url}", fallbackFactory = MyFallbackFactory.class) {
public interface MyFeignClient {

    @PostMapping(value = "/api/dto")
    postDto(@RequestBody Dto dto);
}

使用以下application.yml超时时间约为1 秒,因为 Hystrix 默认为相同的值:

feign:
  hystrix:
    enabled: true
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000

11:52:05.493 INFO 10200 --- [nio-8060-exec-2] com.mycompany.rest.MyController:立即调用 Z50780F4647F68390C45D47D

11:52:06.538 ERROR 24044 --- [nio-8060-exec-1] oac.c.C.[.[.[/].[dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] 抛出异常 [请求处理失败; 嵌套异常是 com.netflix.hystrix.exception.HystrixRuntimeException: MyFeignClient#postDto(Dto) timed-out and fallback failed.] 根本原因


我试过什么?

只要我添加以下几行将超时时间增加到 60 秒,超时就会有效地变为2 秒左右

hystrix:
  command:
    default:
      execution:
        timeout:
          enabled: true
        isolation:
          thread:
            timeoutInMilliseconds: 60000

11:53:33.590 信息 16052 --- [nio-8060-exec-2] com.mycompany.rest.MyController:现在正在调用 Z50780F4645F68390C47D

11:53:35.614 ERROR 16052 --- [nio-8060-exec-2] oac.c.C.[.[.[/].[dispatcherServlet]: Servlet.service() for servlet [dispatcherServlet] in context with path [] 抛出异常 [请求处理失败; 嵌套异常是 com.netflix.hystrix.exception.HystrixRuntimeException: MyFeignClient#postDto(Dto) failed and fallback failed.] 根本原因

只要增加了 Hystrix 读取/连接超时,该调用就会在2 秒内立即进入回退状态。 但是,只要我在feign.client.config.default...超时中声明它,我希望达到5 秒 我觉得我缺少另一个配置。

问:如何增加超时?


编辑:

您的配置是正确的,您所描述的是预期的行为。 这里的问题是,在您配置的超时时间(10 秒)之后,不会抛出Connection refused的异常。 相反,它会在 Java 的内部套接字实现发现服务器主机不可访问后立即抛出。 在最简单的情况下,您调用的服务器没有启动并运行。

至于为什么设置 hystrix 超时后还有第二次增加,可以调试 hystrix 的调用堆栈,发现HystrixRuntimeException没有以相同的顺序抛出。

在您的自定义 hystrix 超时之前,hystrix 的默认超时时间为 1 秒,这意味着此运行时异常总是在执行结束后一秒抛出一次,无论请求是成功还是失败。 因此,在您的情况下, Connection refused很可能在HystrixTimeoutException之后发生。 在您将超时设置为比 feign 客户端更长的时间后, HystrixTimeoutException仅在抛出 feign 异常创建(由于“连接被拒绝”),因此延迟。

// 'cause' should be different due to timing
public HystrixRuntimeException(... Exception cause, Throwable fallbackException)

为了模拟超时,我想说您可以在服务器上强制超时,例如Thread.sleep(6000)以停止服务器端的执行,或者只是在调试器上执行断点。

您可以尝试的一件事是在一行中定义 Hystrix 超时的配置属性(我知道它应该等同于您在 YAML 文件中提出的嵌套定义,但有时我遇到仅在此加载的属性方法)。 正如您在他们的测试中看到的,这是 Spring Cloud 本身配置 Hystrix 超时的方式:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000

此外,尽管您表示您没有使用 Zuul 或 Eureka,但请验证您是否以任何方式使用 Ribbon,存在一些依赖关系(请参阅https://github.com/Netflix/Hystrix/issues/1778https: //github.com/spring-cloud/spring-cloud-netflix/issues/1324 )在 Hystrix 和 Ribbon 超时之间。

如果是这种情况,则必须配置两个库的超时时间:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 5000
ribbon:
  ConnectTimeout: 5000
  ReadTimeout: 5000

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM