Hystrix命令失败,显示“超时且无备用选项”

35
我注意到我的应用程序中的一些命令失败了。
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

这是什么类型的超时?它是针对外部应用程序的读取/连接超时吗?我该如何调试这个问题?

5个回答

40
这是 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

1
如果捕获HystrixTimeoutException并返回自己的异常,会发生什么?断路器还能正常工作吗?还是异常需要传播到某个地方? - Robin Jonsson
@RobinJonsson 异常被称为 HystrixRuntimeException,它对于超时和命令抛出其他异常都是相同的异常。 - Simon Forsberg
@HystrixProperty 的配置在哪里?Zuul 中有吗? - reza ramezani matin

19

可能是由于您正在调试或者您的连接速度较慢, 默认的线程执行超时时间仅为1秒,因此如果您在命令行中设置了断点,您很容易收到此消息。

虽然这不是您的情况,但可能会帮助其他人。


这是我的经验! - abhi

2
在添加以下依赖项后:
   <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属性。
这对我有效,希望对您也有用。

1
查看堆栈跟踪,这是由 Hystrix 在你定义的 210 秒后抛出的异常。
由于 TimeoutException 是一个需要在可能抛出此异常的每个方法中声明的已检查异常。您将在代码的 run() 方法中看到这个声明。
您可以像调试其他程序一样调试它,但请注意,run() 方法在与调用者分开的线程中运行。在 210 秒后,即使您的调试会话仍在进行中,调用者也会继续运行。

我的run()方法只是一个看起来像这样的GET HTTP调用。这是一个Jersey客户端。 ClientResponse response = client.resource(buildUri()).get(ClientResponse.class); - dkulkarni
这是我的代码。就像我说的,它是一个Jersey客户端。<code>@Override protected FetchProvisionedIdsResponse run() throws Exception { ClientResponse response = client.resource(buildUri()) .get(ClientResponse.class); return response.getEntity(MyResponse.class);</code> } - dkulkarni
你在方法中声明了 Exception,一个好的编程习惯是要缩小异常范围。通过API描述我发现 get() 会抛出UniformInterfaceException,但没有 TimeoutException。所以这个异常是由 Hystrix 抛出的。 - ahus1

-2

你应该增加你的 REST 客户端 HttpClient 的 readTimeout 属性。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接