如何在Spring的AsyncRestTemplate上设置超时?

时间:2014-02-21 19:37:55

标签: spring spring-mvc asynchronous resttemplate

我在项目中设置了RestTemplate和AsyncRestTemplate,类似于以下内容:

http://vincentdevillers.blogspot.fr/2013/10/a-best-spring-asyncresttemplate.html

我注意到除非我将httpRequestFactory()bean更改为以下内容,否则连接超时实际上不起作用:

@Bean
public ClientHttpRequestFactory httpRequestFactory() {
    HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient());
    factory.setConnectTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
    factory.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
    return factory;
}

如果我将DEFAULT_READ_TIMEOUT_MILLISECONDS设置为5,则在使用restTemplate(按预期)时会发生超时。但是,当我使用AsyncRestTemplate时,不会发生超时。我已经像httpRequestFactory()那样修改了asyncHttpRequestFactory(),但是没有骰子。

@Bean
public AsyncClientHttpRequestFactory asyncHttpRequestFactory() {
    HttpComponentsAsyncClientHttpRequestFactory factory = new HttpComponentsAsyncClientHttpRequestFactory(asyncHttpClient());
    factory.setConnectTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
    factory.setReadTimeout(DEFAULT_READ_TIMEOUT_MILLISECONDS);
    return factory;
}

以下是我在Spring MVC控制器中尝试使用AsyncRestTemplate的方法:

String url = "...";
// Start the clock
long start = System.currentTimeMillis();

ListenableFuture<ResponseEntity<String>> results = asyncRestTemplate.getForEntity(url, String.class);
// Wait until the request is finished
while (!(results.isDone())) {
    Thread.sleep(10); //millisecond pause between each check
}
System.out.println("Elapsed time: " + (System.currentTimeMillis() - start));
return results.get().getBody();

如何让AsyncRestTemplate读取我的连接超时设置?

在相关的说明中,https://spring.io/guides/gs/async-method/使用@Async和RestTemplate,似乎完成了我正在寻找的东西。使用AsyncRestTemplate而不是RestTemplate有什么好处?

4 个答案:

答案 0 :(得分:4)

AsyncRestTemplate依赖于HTTP客户端的NIO功能,因此您可以使用少量线程管理大量连接。要使用@Async + RestTemplate实现相同功能,需要更多资源。如果你只是在一些地方做这件事,那么它可能还可以,尽管AsyncRestTemplate,因为它存在,对于用例来说更好一些,更专业。

至于读取超时,它看起来可能是疏忽。随意创建一张票。快速浏览this page,&#34; HttpAsyncClient配置&#34;示例,显示使用:

IOReactorConfig.custom().setConnectTimeout(30000)

我想你可以快点试试

答案 1 :(得分:4)

sync非常相似:

final SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
requestFactory.setTaskExecutor(new SimpleAsyncTaskExecutor());
requestFactory.setConnectTimeout(connectTimeout);
requestFactory.setReadTimeout(readTimeout);

final AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate();
asyncRestTemplate.setAsyncRequestFactory(requestFactory); 

source code,您可以看到AsyncRestTemplate实例是使用SimpleClientHttpRequestFactorySimpleAsyncTaskExecutor创建的。因此,您可以使用设置了超时值的SimpleClientHttpRequestFactory实例来执行相同操作。

答案 2 :(得分:3)

我认为AsyncRestTemplate的重点是ListenableFuture(你没有真正使用它的功能)。所以@Async可能适用于您的用例。另外,我认为results.get(5,TimeUnit.SECOND)更有效(和优雅)然后使用Thread.sleep(...)循环,但这取决于你我猜。或许我错过了一些东西。

答案 3 :(得分:0)

{{1}}
像这样,AsyncRestTemplate超时配置是可以的。