产生大量线程从来都不是一个好主意(当创建太多线程时,可能会耗尽内存)。
通常,Jersey需要为每个请求创建一个线程。无论我使用async()
(Jersey为我创建线程-我已经在调试器中对此进行了研究),还是不使用。
因此,这里有一个具体的情况,这还不够好:
我正在以每秒500个请求的速度向远程服务器发送HTTP邮件。但是,由于响应可能需要一些时间才能到达(我计算最多30秒),线程总数很容易达到数千个(此时,JVM进程通常会崩溃)。此外,创建这么多线程简直太疯狂了。对于可用的处理器/网络/OS资源来说,处理这种负载实际上应该是小菜一碟。
因此,我想做的是启动请求,并在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>
希望这能有所帮助。
使用https://github.com/AsyncHttpClient/async-http-client,它使用netty。它将从请求线程发出调用,并对代码进行回调,这样就不会占用容器请求线程。