Jersey客户端非阻塞
派生大量线程从来都不是一个好主意(当您创建太多线程时,无论如何都可能会耗尽内存)。
通常,Jersey需要为每个请求创建一个线程。无论我使用async()
(Jersey为我创建线程-我已经在调试器中研究过这一点),还是不使用(显然我必须自己创建线程),情况似乎都是如此。
所以这里有一个具体的情况,这是不够好的:
我正在以高达500个请求/秒的速度向远程服务器发送HTTP。但是,由于响应可能需要一些时间才能到达(我计算最多30秒),线程总数很容易达到数千(此时,JVM进程通常会崩溃)。此外,创建这么多线程简直是疯了。对于处理该负载的可用处理器/网络/操作系统资源来说,这实际上应该是小菜一碟。
因此,我想要做的就是发出请求,并在HTTP响应到达时得到操作系统的通知。
- 如上所述,简单地使用
target.request(...).async()....
并不能达到目的(因为这样一来,Jersey只会产生自己的线程)。 - 此外,通过
new ClientConfig().property(ClientProperties.ASYNC_THREADPOOL_SIZE, 10)
限制线程数也没有任何帮助,因为这意味着一次最多只能发送10个请求,这显然不是我想要的(这只会堆积队列)。
我尝试了new ClientConfig().connectorProvider(new GrizzlyConnectorProvider())
以获得NIO支持-但在行为上根本看不到任何差异。
那么,有什么方法可以在不为每个请求创建一个额外线程的情况下启动请求吗?
解决方案
我正在使用CloseableHttpAsyncClient向外部服务发出异步请求。它在每秒几百个请求的情况下工作得很好,我还没有观察到像您这样的线程数量。它是一个外部依赖项,您可以通过
通过Maven进行集成<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpasyncclient</artifactId>
<version>4.0.1</version>
</dependency>
希望这能有所帮助。
相关文章