Spring @RestController调用大量请求

时间:2016-11-18 18:53:33

标签: java spring asynchronous spring-restcontroller

我正在使用Spring Boot实现REST API,使用Java 8实现@RestController。其中一个控制器方法需要调用另一个第三方REST API服务。该方法概述如下(数据格式为JSON):

  1. 调用第三方API方法以获取候选人列表(每个候选人都被表示为具有一些基本信息的对象)。
  2. 对于每位候选人,请拨打另一个第三方API方法,以获取有关候选人的更详细信息。
  3. 捣乱结果,基本上是#34;丰富"第一次通话中的所有候选对象。
  4. 返回丰富的候选对象列表。
  5. 我计划在第三方API上使用@RestTemplate进行所有调用。我担心的是,对于大量候选人(比如说500-1000),这将成为一个巨大的性能瓶颈,是以阻塞的方式实现的。我不太确定推荐的最佳性能方法是什么。如何对此进行扩展,以便多个用户可以同时访问我的API?

4 个答案:

答案 0 :(得分:4)

您的问题非常广泛,我认为没有人能够为您提供详细的答案,但是:

  1. 您的案例似乎是RxJava的完美用例:通过添加其他来源的其他信息进行转换的候选流 - 所有这些都是异步的。

  2. 我会跳过RestTemplate并与他们真棒的RxJava集成一起去Retrofit2。请参阅此基本tutorial1tutorial2

  3. 1000条记录并不多,但它也取决于下游服务的性能。您需要自己测试一下。

  4. 如果您想了解更多有关RxJava的内容,有一些great docs online以及Tomasz Nurkiewicz和Ben Christensen的new amazing book

  5. 祝你好运!

答案 1 :(得分:1)

拉法尔已经给出了一个很好的答案。我想加2美分。您的案例似乎是非阻止的完美用例。 RxJava只是非阻塞响应式编程的一种实现。您也可以使用不同的其他技术堆栈来实现相同的功能 - 例如akka或带有netty或underow的spring boot。

这是我们如何使用spring boot进行响应式编程的示例。 https://spring.io/blog/2016/07/28/reactive-programming-with-spring-5-0-m1请记住,它仍处于实验状态。 Reactive streams将内置于Java 9

答案 2 :(得分:0)

您的应用程序服务器将管理线程池,因此许多请求可以同时命中您的端点。除非您的线程池大小为1,否则多个客户端将能够同时使用您的API。

有关详细说明,请参阅此处:Spring MVC Rest Services - Number of Threads (Controller Instances)

请参阅此处了解如何配置线程池大小的示例:Maximum (client request) thread pool size in spring

为了在向外部服务发出请求时提高性能,我会看看您是否可以批量请求(一次多个候选人),以减少您提出的请求总数。

答案 3 :(得分:0)

对旧线程的响应。下面是一些可以使用的东西。

  1. 使用 AsyncHttp 而不是 RestTemplate。
  2. 设置单独的线程池(Executor Service)以进行外部调用。
  3. 尽可能使用 Java 8 CompletableFuture.supplyAsync(() -> externalCall(),executorService) 调用外部 API。对于第 3 方调用和嵌套调用。
  4. 将用 CompletableFuture 包裹的混搭对象返回给控制器。