java - 带有 Hystrix 断路器超时的 Spring Cloud Feign 客户端默认为 2 秒
问题描述
可通过 GitHub 上的项目重现:spring-cloud-feign-hystrix-timeout-problem
我正在将 Spring Boot2.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.RELEASE
和Spring Cloud Hoxton.SR6
:
org.springframework.boot
:spring-boot-starter
org.springframework.boot
:spring-boot-starter-web
org.springframework.cloud
:spring-cloud-starter-openfeign
org.springframework.cloud
:spring-cloud-starter-netflix-hystrix
我启用@EnableFeignClients
并@EnableCircuitBreaker
使用@FeignClient
带有简单回退的 a 来记录和重新抛出异常:
@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:现在调用 REST!
11:52:06.538 错误 24044 --- [nio-8060-exec-1] oaccC[.[.[/].[dispatcherServlet]:Servlet.service() 用于路径 [] 上下文中的 servlet [dispatcherServlet] 引发异常[请求处理失败;嵌套异常是 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 INFO 16052 --- [nio-8060-exec-2] com.mycompany.rest.MyController:现在调用 REST!
11:53:35.614 错误 16052 --- [nio-8060-exec-2] oaccC[.[.[/].[dispatcherServlet] :Servlet.service() 用于路径 [] 上下文中的 servlet [dispatcherServlet] 引发异常[请求处理失败;嵌套异常是 com.netflix.hystrix.exception.HystrixRuntimeException: MyFeignClient#postDto(Dto) failed and fallback failed.] 根本原因
只要增加了 Hystrix 读取/连接超时,该调用就会在2 秒内立即进入回退状态。但是,只要我在超时中声明它,我希望达到5 秒。feign.client.config.default...
我觉得我缺少另一个配置。
问:如何增加超时?
编辑:
mvn dependency:tree
: https://pastebin.com/LJFGaMTcpom.xml
:https ://pastebin.com/98uXHTaR- 堆栈跟踪:https ://pastebin.com/7rQweC8w
解决方案
您的配置是正确的,您所描述的是预期的行为。这里的问题是Connection refused
在您配置的超时后不会抛出异常 - 10 秒。相反,它会在 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)
在服务器端停止执行,或者在调试器上简单地做一个断点。
推荐阅读
- swift - SwiftUI @EnvironmentObject 在嵌套视图中共享
- java - 如何将泛型接口的类型绑定到另一个泛型接口?
- php - 嵌套递归函数抛出错误
- sql - 如何使用 UPDATE JOIN 从多行更新单行
- javascript - 我需要创建一个基于输入数组为每个项目创建一个新循环的逻辑
- arrays - 在堆和堆栈上分配的数组的内存地址
- git - 在使用源代码管理时,我如何才能对源代码的不同部分的用户组拥有不同的权限?
- r - 如何根据条件提取行?
- python - 根据 pandas 中的列值创建一个热列名称
- python - 从第二个类调用方法来更新 QListView 数据