【问题标题】:Spring external client timeoutSpring外部客户端超时
【发布时间】:2018-04-30 13:02:05
【问题描述】:

在我们的 Spring 应用程序中,我们依赖外部系统。 我们想为对该系统的请求设置超时,但不知道如何配置。

我们使用这个:

   return clientBuilder.build()
            .target(baseUrl)
            .register(jsonProvider)
            .register(jsonAcceptHeaderClientRequestFilter)
            .register(new LoggingFilter());

我试过这个: How to set the connection and read timeout with Jersey 2.x? 和许多其他建议,但无法使其正常工作。任何建议将不胜感激。

更新不起作用的东西:

.property("http.connection.timeout", 1)
.property("http.receive.timeout", 1)

还有

.property(ClientProperties.CONNECT_TIMEOUT,1)
.property(ClientProperties.READ_TIMEOUT,1)

【问题讨论】:

  • 它是否必须特定于external system 的请求?我知道您可以使用 server.connection-timeout 属性全局配置请求超时。见stackoverflow.com/questions/44274982/…
  • 这是否也会影响对我们系统的请求超时?
  • 是的,很遗憾。我不知道通过请求设置超时的任何方法,因为它似乎是由嵌入式服务器 (Tomcat) 管理的,但其他地方可能有替代方法
  • 嗯,按照那个 Jersey 超时链接上的建议,尝试 target(baseUrl).property(ClientProperties.CONNECT_TIMEOUT, 1)target(baseUrl).property(ClientProperties.READ_TIMEOUT, 1) 都会在本地导致 javax.ws.rs.ProcessingException: java.net.SocketTimeoutException 失败。不过,您似乎不太可能没有尝试过 - 感觉好像还有比上面的示例更多的事情? (这是使用 jersey-client-2.14)

标签: java spring restclientbuilder


【解决方案1】:

正如您问题中链接的答案所证实的那样,@df778899 的 cmets 之一,根据我的测试,对于jersey 客户端,以下用法正常

target(baseUrl)
.property(ClientProperties.CONNECT_TIMEOUT, 1000)
.property(ClientProperties.READ_TIMEOUT, 1000)

如果外部服务器在设定的时间内没有响应,则产生java.net.SocketTimeoutException

对于Apache CXF 客户端,我在 sn-p 下进行了测试,它适用于读取超时。而且,这是官方的reference。在该页面中搜索下面sn-p中使用的参数。

注意:有关支持此功能的版本,请查看JIRA

target(baseUrl)
.property("http.connection.timeout", 5000)
.property("http.receive.timeout", 5000)

更新OP 可能不需要以下内容,但出于学术考虑而保留。 .

我的直觉是,你追求不同的目标。在我看来,您的外部系统实际上正在响应,但速度可能比您期望的要慢,或者响应本身更大,从而消耗的时间比您期望的要长?

在这种情况下,您可以调整超时参数。但是,它们在循环套接字读取的基础上工作。因此,假设您将超时设置为X,并且您的响应数据为Y 字节。缓慢的读取可能意味着 socket.read() 调用带有数据,但内容是 1/2 字节。 X 适用于每次读取。所以理论上完整的阅读可能需要X*Y ms。

如果以上确实是您的问题,那么您可能需要使用外部计时器来解决此问题。例如,您可以:

  1. 通过ExecutorService.submit(Callable< T> task)进行外部服务调用
  2. 然后,调用生成的Future.get(long timeout, TimeUnit unit)

【讨论】:

  • 客户端超时似乎没有受到影响,但类本身不是来自球衣包,而是来自org.apache.cxf.jaxrs.client.spec.ClientImpl。 'http.connect.timeout' 也不起作用。
  • 这些属性似乎也被完全忽略了
  • 对不起朋友。这些道具应该可以在带有org.apache.cxf:cxf-rt-rs-client:3.1.11 的普通springboot 应用程序中为我工作。我通过按描述设置超时并将网址指向http://localhost:port 并使用nc -l port 来设置一个没有响应的虚拟侦听器来进行测试。也许您可以尝试一次,以确定您面临的问题是套接字超时不起作用还是其他原因。
  • 那条评论帮助了我。在 apache cxf 3.0.0 上,那些 http 超时被忽略,但是在更新到 3.1.11 之后(因为这对你有用) SocketTimeOut 被抛出。非常感谢
  • 很高兴为您提供帮助。这具有修复版本:issues.apache.org/jira/browse/CXF-6353。在答案中更新。
【解决方案2】:

您可以使用server.connection-timeout,但这将为所有请求设置超时,而不仅仅是向外部系统发出的请求。

server.connection-timeout= # 连接器在关闭之前等待另一个 HTTP 请求的时间 联系。未设置时,连接器的容器特定默认值 用来。使用值 -1 表示否(即无限) 超时。

Reference

【讨论】:

  • 对我们系统的请求可能比请求外部系统数据所用的超时时间更长。所以这不是一个真正的选择
猜你喜欢
  • 1970-01-01
  • 2019-05-05
  • 2012-03-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
相关资源
最近更新 更多