Timeout Handling

在 HTTP 组成的上下文中,必须考虑两个时间区域:

  • 与 Spring 集成通道交互时超时

  • 与远程 HTTP 服务器交互时超时

组件与消息通道进行交互,可以为此指定超时。例如,HTTP 入站网关会将从连接的 HTTP 客户端接收到的消息转发到消息通道(使用请求超时),因此 HTTP 入站网关会从使用回复超时的回复通道(用于生成 HTTP 响应)接收回复消息。下图提供了一个直观的解释: .How timeout settings apply to an HTTP Inbound Gateway image::http-inbound-gateway.png[] 对于出站端点,我们需要考虑与远程服务器交互时的时间工作原理。下图显示了此方案: .How timeout settings apply to an HTTP Outbound Gateway image::http-outbound-gateway.png[] 当使用 HTTP 出站网关或 HTTP 出站通道适配器进行主动 HTTP 请求时,您可能希望配置与 HTTP 相关的超时行为。在这些情况下,这两个组件使用 Spring 的 link:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html[RestTemplate 支持来执行 HTTP 请求。 要为 HTTP 出站网关和 HTTP 出站通道适配器配置超时,您可以直接引用一个 RestTemplate bean(通过使用 rest-template 属性),或者可以引用 link:https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/client/ClientHttpRequestFactory.html[ClientHttpRequestFactory bean(通过使用 request-factory 属性)。Spring 提供了 ClientHttpRequestFactory 界面的以下实现:

如果你没有显式配置 request-factoryrest-template 属性,则会实例化一个默认 RestTemplate(使用 SimpleClientHttpRequestFactory)。

在一些 JVM 实现中,URLConnection 类对超时处理可能不一致。 例如,在 Java™ 平台中,标准版 6 API 规范中对 setConnectTimeout 进行了说明: Some non-standard implementation of this method may ignore the specified timeout. To see the connect timeout set, please call getConnectTimeout(). 如果您有具体需求,您应该测试您的超时。考虑使用 HttpComponentsClientHttpRequestFactory,它反过来使用 Apache HttpComponents HttpClient,而不是依赖于 JVM 提供的实现。

当您将 Apache HttpComponents HttpClient 与池化连接管理器一起使用时,您应该意识到,默认情况下,连接管理器为每个给定的路由创建最多两个并发连接,并且总共创建最多 20 个连接。对于许多实际应用程序,这些限制可能过于严格。请参阅 Apache documentation 以获取有关配置此重要组件的信息。

以下示例通过使用一个 SimpleClientHttpRequestFactory 配置了 HTTP 出站网关,该 SimpleClientHttpRequestFactory 被分别配置了 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-timeoutreply-timeout 映射到了 org.springframework.integration.http.outbound.HttpRequestExecutingMessageHandler 类的 sendTimeout 属性。更准确地说,该属性设置在扩展的 AbstractReplyProducingMessageHandler 类上,而该类最终将该属性设置在 MessagingTemplate 上。 sendTimeout 属性的默认值是 30 秒,并将应用于已连接的 MessageChannel。这意味着,根据实现,消息通道的 send 方法可能会无限期地阻塞。此外,sendTimeout 属性仅在实际的消息通道实现具有阻塞发送(例如,有界队列通道“full”)时使用。

HTTP Inbound Gateway

对于 HTTP 入站网关,XML 架构定义了 request-timeout 属性,该属性用于设置 HttpRequestHandlingMessagingGateway 类(在扩展类 MessagingGatewaySupport 上)上的 requestTimeout 属性。您还可以使用 reply-timeout 属性映射到同类上的 replyTimeout 属性。

这两个超时属性的默认值为 1000ms(一千毫秒或一秒)。最终,request-timeout 属性用于在 MessagingTemplate 实例上设置 sendTimeout。另一方面,replyTimeout 属性用于在 MessagingTemplate 实例上设置 receiveTimeout 属性。

要模拟连接超时,您可以连接到不可路由的 IP 地址,例如 10.255.255.10。