我试图理解restTemplate中的readTimeout,它到底是什么?
它是请求在超时异常之前可以花费的总时间吗?
我试图理解restTemplate中的readTimeout,它到底是什么?
它是请求在超时异常之前可以花费的总时间吗?
据我所知,在RestTemplate中我们有三种类型的超时时间
ConnectionRequestTimeout。获取连接管理器连接的毫秒超时时间
ConnectionTimeout。在源和目标之间建立连接的毫秒超时时间
ReadTimeout。期望从目标终端点返回响应/结果的毫秒超时时间
您可以按以下方式在 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的请求都将失败,并引发超时异常。
您还可以定义一个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之间是单例一样。所以请注意这一点,我不知道是否是我的配置错误、缺陷或预期行为。
我知道这不是原帖的问题,但我怀疑很多人(包括我自己)来到这里是想找到如何设置读取超时时间,而不仅仅是它是什么。
现有的两个代码示例在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)。