Sam*_*Sam 4 java resttemplate java-8 spring-web
我有一个使用 springs RestTemplate 调用多个 url 的服务。
为了提高性能,我想并行执行这些请求。我可以使用的两个选项是:
只是想知道在阻塞 I/O 调用中使用并行流是否是最佳实践?
AForkJoinPool不适合进行 IO 工作,因为您无法从其工作窃取属性中获得任何好处。如果您计划使用commonPool和应用程序的其他部分,您可能会干扰它们。ExecutorService例如,专用线程池可能是这两者中更好的解决方案。
我想提出更好的建议。与其自己编写所有异步包装代码,不如考虑使用 Spring 的AsyncRestTemplate. 它包含在 Spring Web 库中,其 API 几乎与RestTemplate.
Spring 用于异步客户端 HTTP 访问的中心类。公开与 类似的方法
RestTemplate,但返回ListenableFuture包装器而不是具体结果。[...]
注意:默认情况下
AsyncRestTemplate依赖于标准的 JDK 工具来建立 HTTP 连接。您可以通过使用接受AsyncClientHttpRequestFactory.
ListenableFuture实例可以通过 轻松转换为CompletableFuture实例ListenableFuture::completable()。
正如 Javadoc 中所述,您可以通过指定一个AsyncClientHttpRequestFactory. 对于列出的每个库,都有许多内置实现。在内部,其中一些库可能会按照您的建议执行并在专用线程池上运行阻塞 IO。其他的,比如 Netty(如果有内存的话),使用非阻塞 IO 来运行连接。你可能会从中获得一些好处。
然后由您决定如何减少结果。使用CompletableFuture,您可以访问anyOf和allOf帮助程序以及任何组合实例方法。
例如,
URI exampleURI = URI.create("https://www.stackoverflow.com");
AsyncRestTemplate template = new AsyncRestTemplate/* specific request factory*/();
var future1 = template.exchange(exampleURI, HttpMethod.GET, null, String.class).completable();
var future2 = template.exchange(exampleURI, HttpMethod.GET, null, String.class).completable();
var future3 = template.exchange(exampleURI, HttpMethod.GET, null, String.class).completable();
CompletableFuture.allOf(future1, future2, future3).thenRun(() -> {
// you're done
});
Run Code Online (Sandbox Code Playgroud)
AsyncRestTemplate此后已被弃用,取而代之的是 Spring Web Flux' WebClient。这个 API 有很大的不同,所以我不会深入研究它(除了说它确实让你得到了一个CompletableFuture)。
| 归档时间: |
|
| 查看次数: |
7894 次 |
| 最近记录: |