Hystrix 命令因“超时且没有可用的回退”而失败
Posted
技术标签:
【中文标题】Hystrix 命令因“超时且没有可用的回退”而失败【英文标题】:Hystrix command fails with "timed-out and no fallback available" 【发布时间】:2015-02-07 03:29:09 【问题描述】:我注意到我的应用程序中的一些命令失败了
Caused by: ! com.netflix.hystrix.exception.HystrixRuntimeException: GetAPICommand timed-out and no fallback available.
out: ! at com.netflix.hystrix.HystrixCommand.getFallbackOrThrowException(HystrixCommand.java:1631)
out: ! at com.netflix.hystrix.HystrixCommand.access$2000(HystrixCommand.java:97)
out: ! at com.netflix.hystrix.HystrixCommand$TimeoutObservable$1$1.tick(HystrixCommand.java:1025)
out: ! at com.netflix.hystrix.HystrixCommand$1.performBlockingGetWithTimeout(HystrixCommand.java:621)
out: ! at com.netflix.hystrix.HystrixCommand$1.get(HystrixCommand.java:516)
out: ! at com.netflix.hystrix.HystrixCommand.execute(HystrixCommand.java:425)
out: Caused by: ! java.util.concurrent.TimeoutException: null
out: !... 11 common frames omitted
这是我的 Hystrix 配置覆盖:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=210000
hystrix.threadpool.default.coreSize=50
hystrix.threadpool.default.maxQueueSize=100
hystrix.threadpool.default.queueSizeRejectionThreshold=50
这是什么类型的超时?是否是外部应用程序的读取/连接超时?我该如何调试呢?
【问题讨论】:
【参考方案1】:查看堆栈跟踪,这是 Hystrix 在您上面定义的 210 秒后抛出的异常。
因为TimeoutException
是一个检查异常,需要在每个可能抛出此异常的方法上声明。您会在代码的 run()
方法中看到此声明。
您可以像调试任何其他程序一样对其进行调试,但请注意run()
方法在与调用者分开的线程中运行。 210 秒后,尽管您进行了调试会话,调用者仍将继续。
【讨论】:
我的 run() 方法只是一个 GET HTTP 调用,看起来像这样。这是球衣客户。 ClientResponse response = client.resource(buildUri()) .get(ClientResponse.class); 这是我的代码。就像我说的那样,它是一个球衣客户端@Override protected FetchProvisionedIdsResponse run() throws Exception ClientResponse response = client.resource(buildUri()) .get(ClientResponse.class);返回 response.getEntity(MyResponse.class);
你在方法中声明了Exception
,一个好的风格是缩小范围。从 API 描述中我看到get()
会抛出UniformInterfaceException
,但不会抛出TimeoutException
。因此是 Hystrix 抛出了这个异常。【参考方案2】:
可能是你在调试或者你的连接太慢,默认线程执行超时只有 1 秒,所以如果你在你的命令中设置一个断点,你可以很容易地得到这个消息,比如说
虽然这不是你的情况,但可能会帮助其他人
【讨论】:
这就是我的经历!【参考方案3】:你应该增加你的休息客户端httpclient readTimeout属性
【讨论】:
【参考方案4】:这是一个 Hystrix 命令超时,默认情况下每个命令都会启用此超时,您可以使用属性定义值:
execution.isolation.thread.timeoutInMilliseconds: 此属性以毫秒为单位设置时间,在此之后调用者将 观察超时并离开命令执行。 Hystrix 将 > HystrixCommand 标记为 TIMEOUT,并执行回退逻辑。
因此,您可以使用以下属性为您的命令增加超时值或禁用默认超时(如果适用于您的情况):
@HystrixProperty(name = "hystrix.command.default.execution.timeout.enabled", value = "false")
您可以在这里找到更多信息:https://github.com/Netflix/Hystrix/wiki/Configuration#CommandExecution
【讨论】:
如果你捕获 HystrixTimeoutException 并返回你自己的异常会发生什么?断路器还能工作吗?还是异常需要传播到某个地方? @RobinJonsson 该异常被称为HystrixRuntimeException
,它与命令抛出另一个异常的超时异常相同。
在哪里配置@HystrixProperty?有zuul吗?【参考方案5】:
添加如下依赖后
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>1.5.18</version>
</dependency>
我将能够解决超时问题。
你需要做的是在application.properties或者bootstrap.properties中设置hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=210000
属性
这对我有用,希望能奏效。
【讨论】:
以上是关于Hystrix 命令因“超时且没有可用的回退”而失败的主要内容,如果未能解决你的问题,请参考以下文章
SpringCloud---服务容错保护---Spring Cloud Hystrix