超时处理
在HTTP组件的上下文中,有两个需要考虑的计时区域:
-
与 Spring Integration Channels 交互时的超时
-
与远程 HTTP 服务器交互时的超时
组件与消息通道进行交互,可以为这些通道指定超时时间。例如,HTTP 入站网关将从连接的 HTTP 客户端接收到的消息转发到消息通道(该通道使用请求超时),随后 HTTP 入站网关从回复通道(该通道使用回复超时)接收回复消息,用于生成 HTTP 响应。以下插图提供了直观的解释:
图 1. 超时设置如何应用于 HTTP 入站网关
对于出站端点,我们需要考虑在与远程服务器交互时定时的工作方式。下图显示了这种场景:
图 2. 超时设置如何应用于 HTTP 外发网关
你可能需要配置与 HTTP 相关的超时行为,当使用 HTTP outbound 网关或 HTTP outbound 通道适配器进行主动 HTTP 请求时。在这些情况下,这两个组件使用 Spring 的 RestTemplate 支持来执行 HTTP 请求。
要为 HTTP outbound 网关和 HTTP outbound 通道适配器配置超时,你可以直接引用一个 RestTemplate
bean(通过使用 rest-template
属性),或者你可以提供对 ClientHttpRequestFactory bean 的引用(通过使用 request-factory
属性)。Spring 提供了以下 ClientHttpRequestFactory
接口的实现:
-
SimpleClientHttpRequestFactory: 使用标准 J2SE 功能进行 HTTP 请求
-
HttpComponentsClientHttpRequestFactory: 使用 Apache HttpComponents HttpClient (自 Spring 3.1 起)
如果您没有显式配置 request-factory
或 rest-template
属性,则会实例化一个默认的 RestTemplate
(它使用 SimpleClientHttpRequestFactory
)。
在某些 JVM 实现中,URLConnection
类对超时的处理可能不一致。
例如,来自 Java™ 平台,标准版 6 API 规范关于 setConnectTimeout
的描述:
某些非标准实现可能会忽略指定的超时。要查看已设置的
连接超时
,请调用 getConnectTimeout()。
如果有特定需求,你应该测试你的超时设置。可以考虑使用 HttpComponentsClientHttpRequestFactory
,它反过来使用 Apache HttpComponents HttpClient,而不是依赖于 JVM 提供的实现。
当你使用带有连接池管理器的 Apache HttpComponents HttpClient 时,你应该注意,默认情况下,连接管理器为每个给定路由创建的并发连接数不超过 2 个,总连接数不超过 20 个。对于许多实际应用来说,这些限制可能过于严格。有关配置这个重要组件的信息,请参阅 Apache 文档。
以下示例使用 SimpleClientHttpRequestFactory
配置了一个 HTTP 外发网关,该工厂分别配置了 5 秒 的连接和读取超时:
<int-http:outbound-gateway url="https://samples.openweathermap.org/data/2.5/weather?q={city}"
http-method="GET"
expected-response-type="java.lang.String"
request-factory="requestFactory"
request-channel="requestChannel"
reply-channel="replyChannel">
<int-http:uri-variable name="city" expression="payload"/>
</int-http:outbound-gateway>
<bean id="requestFactory"
class="org.springframework.http.client.SimpleClientHttpRequestFactory">
<property name="connectTimeout" value="5000"/>
<property name="readTimeout" value="5000"/>
</bean>
HTTP 外发网关
对于 HTTP 外发网关,XML 模式仅定义了 reply-timeout。reply-timeout 映射到 org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler 类的 sendTimeout 属性。更准确地说,该属性设置在扩展的 AbstractReplyProducingMessageHandler
类上,最终将属性设置在 MessagingTemplate
上。
sendTimeout 属性的值默认为 30
秒,并将应用于连接的 MessageChannel
。这意味着,根据实现的不同,消息通道的 send 方法可能会无限期阻塞。此外,只有在实际的 MessageChannel 实现具有阻塞发送(例如 'full' 有界 QueueChannel)时,才会使用 sendTimeout 属性。
HTTP 入站网关
对于 HTTP 入站网关,XML 模式定义了 request-timeout
属性,用于设置 HttpRequestHandlingMessagingGateway
类(扩展的 MessagingGatewaySupport
类)上的 requestTimeout
属性。你也可以使用 reply-timeout
属性来映射到同一类上的 replyTimeout
属性。
两个超时属性的默认值都是 1000ms
(一千 毫秒或一 秒)。最终,request-timeout
属性用于设置 MessagingTemplate
实例的 sendTimeout
。而 replyTimeout
属性则用于设置 MessagingTemplate
实例的 receiveTimeout
属性。
要模拟连接超时,你可以连接到一个不可路由的 IP 地址,例如 10.255.255.10。