首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring RestTemplate -异步与同步restTemplate

Spring RestTemplate -异步与同步restTemplate
EN

Stack Overflow用户
提问于 2015-07-22 19:38:16
回答 3查看 57.5K关注 0票数 20

我编写了以下代码来测试同步RestTemplate和AsyncRestTemplate的性能。我只是在邮递员上手动运行了几次。

我们只是将10个引用传递到一个GET调用中,这样我们就可以返回10个链接:

RestTemplate -同步和返回( 2806ms: )

代码语言:javascript
复制
ArrayList<String> references = new ArrayList<>();
ArrayList<String> links = new ArrayList<>();
RestTemplate restTemplate = new RestTemplate(); 
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
for (int i = 0; i < 10; i++) {
    ResponseEntity<String> resource = restTemplate.getForEntity(references.get(i), String.class);
    links.add(resource.getBody().toString());
}

RestTemplate -2794ms中的异步和返回:

代码语言:javascript
复制
//Creating a synchronizedList so that when the async resttemplate returns, there will be no concurrency issues
List<String> links = Collections.synchronizedList(new ArrayList<String>());

//CustomClientHttpRequestFactory just extends SimpleClientHttpRequestFactory but disables automatic redirects in SimpleClientHttpRequestFactory
CustomClientHttpRequestFactory customClientHttpRequestFactory = new CustomClientHttpRequestFactory();
//Setting the ThreadPoolTaskExecutor for the Async calls
org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor pool = new org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor();
pool.setCorePoolSize(5);
pool.setMaxPoolSize(10);
pool.setWaitForTasksToCompleteOnShutdown(true);
pool.initialize();
//Setting the TaskExecutor to the ThreadPoolTaskExecutor
customClientHttpRequestFactory.setTaskExecutor(pool);

ArrayList<String> references = new ArrayList<>();
ArrayList<String> links = new ArrayList<>();
AsyncRestTemplate asyncRestTemplate = new AsyncRestTemplate(customClientHttpRequestFactory); 
restTemplate.getMessageConverters().add(new StringHttpMessageConverter());
for (int i = 0; i < 10; i++) {
    Future<ResponseEntity<String>> resource = asyncRestTemplate.getForEntity(references.get(i), String.class);
    ResponseEntity<String> entity = resource.get(); //this should start up 10 threads to get the links asynchronously
    links.add(entity.getBody().toString());
}

在大多数情况下,这两种方法实际上以非常相似的时间返回结果,异步调用和同步调用的平均时间都是2800 most。

我是不是做了一些不正确的事情,因为我本以为异步调用会快得多呢?

EN

回答 3

Stack Overflow用户

发布于 2019-06-25 10:58:27

现在,AsyncRestTemplate@Deprecated而支持WebClient。所以没人应该再用那门课了!

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/reactive/function/client/WebClient.html

票数 21
EN

Stack Overflow用户

发布于 2017-07-22 08:12:37

我想说的是,您错过了AsyncRest的真正好处。您应该在发送的每个请求中添加回调,以便只有在可用时响应才是进程。

实际上,getForEntity方法的AsyncRestTemplate返回一个ListenableFuture,您可以连接回调任务。有关更多信息,请参见官方文档ListenableFuture

例如,在您的情况下,可以是:

代码语言:javascript
复制
for (int i = 0; i < 10; i++) {
     ListenableFuture<ResponseEntity<String>> response = asyncRestTemplate.getForEntity(references.get(i), String.class);
     response.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
            @Override
            public void onSuccess(ResponseEntity<String> result) {
                // Do stuff onSuccess 
                links.add(result.getBody().toString());
            }

            @Override
            public void onFailure(Throwable ex) {
                log.warn("Error detected while submitting a REST request. Exception was {}", ex.getMessage());
            }
        });
}
票数 17
EN

Stack Overflow用户

发布于 2015-07-22 20:26:16

Java的棘手之处在于它是不可组合的,而且很容易阻止。

在这种情况下,调用future.get()会阻塞代码并等待响应返回。实际上,这种方法会进行顺序调用,而不会利用这个RestTemplate实现的异步特性。

解决这一问题的最简单方法是将其分为两个循环:

代码语言:javascript
复制
ArrayList<Future<ResponseEntity<String>>> futures = new ArrayList<>();

for (String url : references.get()) {
    futures.add(asyncRestTemplate.getForEntity(url, String.class)); //start up to 10 requests in parallel, depending on your pool
}

for (Future<ResponseEntity<String>> future : futures) {
    ResponseEntity<String> entity = future.get(); // blocking on the first request
    links.add(entity.getBody().toString());
}

显然,有更优雅的解决方案,特别是如果使用JDK8流、lambdas和ListenableFuture/CompletableFuture或组合库。

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31572475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档