繁体   English   中英

使用 Resttemplate 的多个异步 HTTP 请求

[英]Multiple asynchronous HTTP requests using Resttemplate

我有一个使用 springs RestTemplate 调用多个 url 的服务。

为了提高性能,我想并行执行这些请求。 我可以使用的两个选项是:

  • java 8 并行流利用 fork-join 公共池
  • 使用隔离线程池的可完成未来

只是想知道在阻塞 I/O 调用中使用并行流是否是最佳实践?

ForkJoinPool不适合进行 IO 工作,因为您无法从其工作窃取属性中获得任何好处。 如果您计划使用commonPool并且您的应用程序的其他部分也这样做,您可能会干扰它们。 专用线程池,例如ExecutorService ,可能是这两者中更好的解决方案。

我想提出更好的建议。 与其自己编写所有异步包装代码, AsyncRestTemplate考虑使用 Spring 的AsyncRestTemplate 它包含在 Spring Web 库中,其 API 几乎与RestTemplate相同。

Spring 用于异步客户端 HTTP 访问的中心类。 公开与RestTemplate类似的方法,但返回ListenableFuture包装器,而不是具体结果。

[...]

注意:默认情况下, AsyncRestTemplate依赖于标准的 JDK 工具来建立 HTTP 连接。 通过使用接受AsyncClientHttpRequestFactory的构造函数,您可以切换到使用不同的 HTTP 库,例如 Apache HttpComponents、Netty 和AsyncClientHttpRequestFactory

ListenableFuture实例可以通过ListenableFuture::completable()轻松转换为CompletableFuture实例。

正如 Javadoc 中所述,您可以通过指定AsyncClientHttpRequestFactory来控制要使用的异步机制。 对于列出的每个库,都有许多内置实现。 在内部,其中一些库可能会按照您的建议执行并在专用线程池上运行阻塞 IO。 其他的,比如 Netty(如果有内存的话),使用非阻塞 IO 来运行连接。 你可能会从中获得一些好处。

然后由您决定如何减少结果。 使用CompletableFuture ,您可以访问anyOfallOf助手以及任何组合实例方法。

例如,

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
});

AsyncRestTemplate已被弃用,取而代之的是 Spring Web Flux 的WebClient 这个 API 有很大的不同,所以我不会深入研究它(除了说它确实让你得到一个CompletableFuture )。

Completable future 将是一个更好的方法,因为它在语义上与任务更相关,并且您可以在任务进行时保持代码流运行。

如果您使用流,除了内部异常处理的 lambdas 的笨拙以及它与任务没有那么相关的事实之外,在语义上就像在管道中一样,您将不得不等待所有它们完成,即使它们正在发生在平行下。 为了避免这种情况,您将需要期货,但随后您将回到第一个解决方案。

您可以考虑混合使用,使用流来创建期货。 但鉴于它是一组阻塞 IO 请求,您可能没有足够的请求或时间来利用并行流,库可能不会为您并行拆分任务,您最好使用循环.

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM