Spring RestTemplate 读取超时时间

14

我试图理解restTemplate中的readTimeout,它到底是什么?

它是请求在超时异常之前可以花费的总时间吗?

4个回答

47

据我所知,在RestTemplate中我们有三种类型的超时时间

  1. ConnectionRequestTimeout。获取连接管理器连接的毫秒超时时间

  2. ConnectionTimeout。在源和目标之间建立连接的毫秒超时时间

  3. ReadTimeout。期望从目标终端点返回响应/结果的毫秒超时时间


2
这应该真正成为被选中的答案,因为它以整洁的方式直接回答了提问者的问题。 - AttitudeL
11
当从服务器接收到两个数据部分之间的时间大于超时值时,会发生读取超时。您认为它是响应的总时间,这是不正确的:总时间可能大于超时值。 - wcislo
1
@wcislo 有没有办法限制总时间,比如1分钟,以接收完整的响应。 - Dhruvam Gupta
@DhruvamGupta 在 RestTemplate 之外,例如 http://iteratrlearning.com/java9/2016/09/13/java9-timeouts-completablefutures.html。 - Simon Logic

17

您可以按以下方式在 RestTemplate 上定义读取超时时间:

HttpComponentsClientHttpRequestFactory clientRequestFactory = new HttpComponentsClientHttpRequestFactory();
// set the read timeout, this value is in milliseconds
clientRequestFactory.setReadTimeout(500);

RestTemplate restTemplate = new RestTemplate(clientRequestFactory);

给定一个X毫秒的readTimeout,通过该RestTemplate实例发出的任何请求,如果超过X毫秒,则会导致ResourceAccessException异常,其中包含一个java.net.SocketTimeoutException异常信息:"Read timed out"。

超时实际上是由RestTemplate包装的HttpClient实例内部的套接字连接器实现的,因此当请求第一次到达该套接字并且满足以下条件之一时,计时器开始计时并停止:请求完成或达到readTimeout。

实际上,这意味着任何超过配置的readTimeout的请求都将失败,并引发超时异常。


1
请注意,readTimeout不能保证完整响应到达时间限制:了解URLConnection.setReadTimeout() - Vadzim

11

您还可以定义一个bean:

@Bean
public RestTemplate restTemplateReadTimeout(RestTemplateBuilder builder) {
    return builder
            .setReadTimeout(15000) //15 seconds
            .build();
}

并使用它:

@Autowired
@Qualifier("restTemplateReadTimeout")
private RestTemplate restTemplate;

顺便提一句,当我在Spring Boot上使用此配置时,我尝试创建具有不同超时配置的不同RestTemplate Bean。但最终我看到Spring仅使用一个超时配置(可能使用最后注册的Bean的超时配置),就像超时配置在RestTemplates之间是单例一样。所以请注意这一点,我不知道是否是我的配置错误、缺陷或预期行为。


2

我知道这不是原帖的问题,但我怀疑很多人(包括我自己)来到这里是想找到如何设置读取超时时间,而不仅仅是它是什么。

现有的两个代码示例在Spring Boot 3 / Spring Framework 6中不再适用,所以这是我找到的最简单的方法:

// Using the builder pattern
restTemplate = new RestTemplateBuilder().setReadTimeout(Duration.ofSeconds(10)).build();

从技术上讲,直接配置连接工厂仍然是可能的,但它比之前的Spring版本更冗长:

要更改套接字读取超时,请使用SocketConfig.Builder.setSoTimeout(Timeout),将得到的SocketConfig提供给org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder.setDefaultSocketConfig(SocketConfig),使用得到的连接管理器org.apache.hc.client5.http.impl.classic.HttpClientBuilder.setConnectionManager(HttpClientConnectionManager),并将构建好的HttpClient提供给HttpComponentsClientHttpRequestFactory(HttpClient)。


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