【问题标题】:Enhancing throughput with async http使用异步 http 提高吞吐量
【发布时间】:2015-11-18 08:19:20
【问题描述】:

在 java web 应用程序中,我想通过以下要求最大化我的服务器吞吐量:

  • 获取多个并发 http 请求的系统。
  • 对于每个请求都需要进行一些处理。
  • 每个请求处理都由几个步骤组成。
  • 最后一步调用外部 API(http 调用)。

这是描述我的系统的基本图:

所以对于每个请求,我都是:

  • 创建 3 个可运行文件并提交(使用我的执行程序)。
  • 然后我正在等待所有 3 个完成并继续处理结果(使用 Guava ListenableFuture 进行处理)
  • 处理完所有返回响应的结果后

在这个设计中,我使用的是同步 http 客户端(在调用外部服务时),这意味着我的每个任务一旦进入第三步就会被阻止,直到 http 响应返回。这可能需要数百毫秒。

我的问题是 - 我想知道使用异步 http 客户端是否可以帮助我提高吞吐量?使用异步 http 客户端,一旦我启动我的 http 请求,任务的线程就会被释放回池中并可用于其他处理,一旦返回 http 响应,就会分配一个新线程来继续任务。是否有意义?如果是这样,它是否取决于 http 外部调用完成所需的时间?如果响应在 5 毫秒后返回,我还会获得额外的吞吐量吗?有人测量过类似的东西吗?

【问题讨论】:

    标签: java multithreading http asynchronous


    【解决方案1】:

    假设你所说的异步客户端不是指 Servlet 异步上下文,而是支持 Futures 或 Callbacks 的 HTTP 客户端的实现,那么使用异步 http 客户端不会有任何好处。

    因为您仍然需要在负责处理请求的容器线程中等待 HTTP 客户端返回的 Future。但是,如果您选择使用回调,我不确定该回调将如何重新启动容器线程以返回响应。 似乎使用回调的正确方法是使用 Servlet 3 异步功能。

    通过使用 Servlet 异步,您将能够节省容器线程上的时间,并且能够在相同的时间内处理更多的请求。同样在这种情况下,不需要使用异步 HTTP 客户端,因为 HTTP API 调用已经在 Servlet 异步线程中。

    如果响应(HTTP API 调用)在 5 毫秒内恢复,您不太可能获得吞吐量。也就是说,我自己没有为此做过任何基准测试,看看这种基准测试的结果会很有趣。

    【讨论】:

    • 您的假设是正确的,我的意思是支持期货或回调的 HTTP 客户端的实现。是的 - 我计划等待容器请求线程(没有详细说明它,因为它使问题复杂化)。无论如何,我的容器请求线程将不得不等待,直到最慢的 http 请求返回,但也许在这段时间内我可以释放任务的线程来处理其他事情,这实际上是我的困境。关于 Servlet 3 的异步能力——我不是很熟悉,我去看看