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 命令因“超时且没有可用的回退”而失败的主要内容,如果未能解决你的问题,请参考以下文章

为啥@jdbc 查询因连接超时而失败?

SpringCloud---服务容错保护---Spring Cloud Hystrix

笔记:Spring Cloud Hystrix 服务容错保护

电脑自检 转

Hystrix 命令不在 Hystrix 环境中运行

Hystrix的正确理解方式