首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与少量线程并发发送大量HTTP请求

与少量线程并发发送大量HTTP请求
EN

Stack Overflow用户
提问于 2022-04-30 07:23:04
回答 2查看 639关注 0票数 3

在我们的代码中,我们需要将大量的HTTP请求并发地发送到服务器端点(每秒数百次请求),连续发送一段时间。服务器需要4-5秒来响应每个请求.

底层代码是使用Apache HttpClient (经典的)发出这些请求。由于这个客户端是阻塞的,所以我不得不使用大量线程(在ExecutorService.newFixedThreadPool()中)并发发送请求,以实现目标:启动这些线程,其中每个线程基本上执行如下操作:

代码语言:javascript
运行
复制
while (time_elapsed < 3600 seconds) {
    sendHttpRequest(); // this takes ~4-5 seconds, during which the current thread is blocked due to the nature of Apache 
}

有两个问题:

  • 由于服务器在4-5秒内响应每个HTTP调用,理论上我们需要400-500个线程才能发送~100个请求/秒,但是这大量的线程将消耗大量的资源,会导致大量的上下文切换和其他问题,因此实际上它们不会发送多达100个请求/秒的请求。
  • 由于每个线程在发送下一个线程之前都要等到当前请求完成(4-5秒),所以我们无法控制每秒钟发送的请求的确切数量。

如果我们能够灵活地切换到异步http客户机(如Apache HttpAsyncClient异步-http-客户机 ),这本来是很容易的,但不幸的是,由于代码库的限制,我们无法做到这一点。

我的问题是,是否有另一种方法可以实现数百个并发请求/秒,即具有少量线程的,而无需使用异步HTTP客户端?CompletableFuture是一个选择吗?

EN

回答 2

Stack Overflow用户

发布于 2022-04-30 07:37:15

虚拟线程

虚拟线程 (纤维 )是为Java 19提出的一种新的预览功能。这是https://wiki.openjdk.java.net/display/loom/Main的一部分,带有实验性构建的现在可以使用

在传统的Java并发中,Java中的线程直接与主机OS线程一对一地映射.问题是,当代码在线程块中运行时,线程也会阻塞。该线程暂停,直到正在执行的代码被解除阻塞。很多时候,一个线程可能会闲置,处于空闲状态,而等待对存储I/O、网络I/O、数据库访问等的调用返回。

相反,许多建议的虚拟线程映射到由主机OS提供的每个“真实”线程。当由虚拟线程块执行代码时,虚拟线程被“停放”,搁置,而另一个虚拟线程在主机OS线程上取代它的位置。当先前的虚拟线程的任务不再被阻塞时,它再次被分配给主机OS线程以继续执行。

这种停车和不停车是非常有效的。这意味着你可以拥有成千上万甚至数百万的同步线程。

因此,您可以将数百个HTTP请求设置为单独的Runnable/Callable任务,然后将它们全部提交到适当的执行器服务中,以便立即执行。

顺便说一下,Java现在包括了一个新HTTP客户端库。

票数 1
EN

Stack Overflow用户

发布于 2022-05-01 23:38:38

您知道Akka异步框架吗?它可以继续工作,而不是在等待响应时阻塞线程。当http请求完成后,您将有一个回调来处理数据。

https://doc.akka.io/docs/akka-http/current/client-side/index.html

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

https://stackoverflow.com/questions/72066501

复制
相关文章

相似问题

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