在我们的代码中,我们需要将大量的HTTP请求并发地发送到服务器端点(每秒数百次请求),连续发送一段时间。服务器需要4-5秒来响应每个请求.
底层代码是使用Apache HttpClient (经典的)发出这些请求。由于这个客户端是阻塞的,所以我不得不使用大量线程(在ExecutorService.newFixedThreadPool()
中)并发发送请求,以实现目标:启动这些线程,其中每个线程基本上执行如下操作:
while (time_elapsed < 3600 seconds) {
sendHttpRequest(); // this takes ~4-5 seconds, during which the current thread is blocked due to the nature of Apache
}
有两个问题:
如果我们能够灵活地切换到异步http客户机(如Apache HttpAsyncClient或异步-http-客户机 ),这本来是很容易的,但不幸的是,由于代码库的限制,我们无法做到这一点。
我的问题是,是否有另一种方法可以实现数百个并发请求/秒,即具有少量线程的,而无需使用异步HTTP客户端?CompletableFuture是一个选择吗?
发布于 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客户端库。
发布于 2022-05-01 23:38:38
您知道Akka异步框架吗?它可以继续工作,而不是在等待响应时阻塞线程。当http请求完成后,您将有一个回调来处理数据。
https://doc.akka.io/docs/akka-http/current/client-side/index.html
https://stackoverflow.com/questions/72066501
复制相似问题