我有一个Servlet,它在启动时构建一个HttpClient实例。它与服务请求时使用的协作模块共享此客户端。我希望在协作模块中使用FutureRequestExecutionService API来轻松地并发发送一些请求。这需要使用HttpClient实例和ExecutorService实例。教程建议将ExecutorService设置为使用与HttpClient的最大并发连接数相同的线程数。
futureRequestExecutionService的构造函数接受任何现有的httpClient实例和ExecutorService实例。在配置这两种连接时,的最大连接数与您将要使用的线程数对齐是很重要的。当线程多于连接时,由于没有可用的连接,连接可能会开始超时。当连接比线程多时,futureRequestExecutionService将不会全部使用它们。
我认为协作模块应该是为并发请求创建ExecutorService的模块。在这种情况下,问题在于协作模块不一定知道它应该使用多少线程,因为它不知道HttpClient被配置为允许多少个同时连接。
我知道我可以使用HttpClient的getConnectionManager方法,但到了4.3岁时,这个方法已被否决。那么,确定给定HttpClient允许多少个同时连接的推荐方法是什么呢?我怀疑错误的答案是保存对用于构建HttpClient的ConnectionManager对象的引用,并将其与协作模块一起传递,或者定义某种全局常量。也许我问错了问题。
也许我应该同时创建HttpClient、ExecutorService和FutureRequestExecutionService对象,然后只将FutureRequestExecutionService实例传递给希望使用共享客户端进行HTTP请求的模块。我想以一种与HttpClient作者的意图相一致的方式这样做;在这种情况下,我只是不确定这到底是什么。
编辑:为了澄清,HttpClient实例是使用为其连接管理器设置了PoolingHttpClientConnectionManager的HttpClientBuilder创建的。但是,这与创建PoolingHttpClientConnectionManager和FutureRequestExecutionService的范围不同。我开始怀疑它们应该一起创建,然后使用FutureRequestExecutionService实例而不是传递FutureRequestExecutionService实例。
发布于 2013-09-26 09:43:49
这里的要点是避免过多的工作线程最终争夺太少的连接,从而造成性能瓶颈的情况。每个路由/总限制的工作线程和连接的数量只需大约合理:例如,12个工作人员和10个连接或10个工作人员和12个连接,但不像12个工人和2个连接。
尽管如此,为了回答您的问题,我不建议紧密耦合PoolingHttpClientConnectionManager和FutureRequestExecutionService布线代码。对我来说,更好的方法应该是拥有一个简单的POJO,甚至是一个表示HTTP服务配置的散列图,所有连接代码都应该依赖这些配置,而不是各种实现类的直接耦合。
这条线上的东西
static class MyHttpServiceConfig {
int workerNum = 10;
};
MyHttpServiceConfig config = new MyHttpServiceConfig();
CloseableHttpClient client = HttpClients.custom()
.setMaxConnPerRoute(config.workerNum)
.build();
ExecutorService executor = Executors.newFixedThreadPool(config.workerNum);
FutureRequestExecutionService executionService = new FutureRequestExecutionService(
client, executor);发布于 2013-09-25 21:46:36
您应该使用PoolingHttpClientConnectionManager来控制httpClient连接的最大数量,可以同时使用。然后,可以将使用此连接管理器创建的httpClient传递到FutureRequestExecutionService构造函数中。
apache 这里也提供了一个示例。
https://stackoverflow.com/questions/19014919
复制相似问题