Java 如何确定给定“HttpClient”实例的最大同时连接数

Java 如何确定给定“HttpClient”实例的最大同时连接数,java,apache-httpclient-4.x,Java,Apache Httpclient 4.x,我有一个Servlet,它在启动时构建一个HttpClient实例。 它与服务请求时使用的协作模块共享此客户端。 我想在中使用API 协作模块可以轻松地同时发送一些请求。 这需要将HttpClient实例与实例一起使用。建议将ExecutorService设置为使用与HttpClient最大并发连接数相同的线程数 futureRequestExecutionService的构造函数接受任何现有的httpClient实例和ExecutorService实例。在配置这两个线程时,将最大连接数与要使用

我有一个
Servlet
,它在启动时构建一个
HttpClient
实例。 它与服务请求时使用的协作模块共享此客户端。 我想在中使用API 协作模块可以轻松地同时发送一些请求。 这需要将
HttpClient
实例与实例一起使用。建议将
ExecutorService
设置为使用与
HttpClient
最大并发连接数相同的线程数

futureRequestExecutionService的构造函数接受任何现有的httpClient实例和ExecutorService实例。在配置这两个线程时,将最大连接数与要使用的线程数对齐非常重要。当线程数大于连接数时,由于没有可用连接,连接可能开始超时。当连接多于线程时,futureRequestExecutionService将不会使用所有连接

我认为协作模块应该是为其并发请求创建
ExecutorService
的模块。这种情况下的问题是,协作模块不一定知道它应该使用多少线程,因为它不知道
HttpClient
已配置为允许多少同时连接

我知道我可以使用
HttpClient
getConnectionManager
方法,但从4.3开始,这是不推荐的。那么,确定给定的
HttpClient
将允许多少同时连接的推荐方法是什么?我怀疑错误的答案是保存对
ConnectionManager
对象的引用,该对象用于构建
HttpClient
,并将其与协作模块一起传递,或者定义某种全局常量。也许我问错问题了

也许我应该同时创建
HttpClient
ExecutorService
FutureRequestExecutionService
对象,然后只传递
FutureRequestExecutionService
要发出HTTP请求的模块的实例 使用共享客户端。我希望这样做的方式与HttpClient作者的意图一致;我只是不确定在这种情况下这到底是什么

编辑:为了澄清这一点,使用为其连接管理器设置了
PoolighttpClientConnectionManager
HttpClient
实例创建了
HttpClientBuilder
。 但是,这与创建
PoolighttpClientConnectionManager
FutureRequestExecutionService
的作用域不同。 我开始怀疑它们应该一起创建,然后使用
FutureRequestExecutionService
实例,而不是传递
HttpClient
实例。

您应该使用它来控制可以同时使用的最大HttpClient连接数。然后,您可以将使用此连接管理器创建的httpClient传递到FutureRequestExecutionService构造函数中


apache也提供了一个示例。

这里的要点是避免太多的工作线程最终争夺太少的连接,从而导致性能瓶颈。每个路由的工作线程和连接数/总限制只需要大约合理:例如,12个工作线程和10个连接,或者10个工作线程和12个连接,但不同于12个工作线程和2个连接

话虽如此,为了回答您的问题,我不建议将
poollighttpclientconnectionmanager
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);

我想你误解了我的问题。我实际上已经在使用PoollightTPClientConnectionManager了。问题是,
HttpClient
&
poollighttpclientconnectionmanager
是在一个类中创建的,
ExecutorService
是在另一个类中创建的。哇,我简直不敢相信我自己从项目负责人那里得到了答案!我将尝试一下(并可能在不久之后接受您的答案)。感谢您对Apache HttpComponents项目的贡献。顺便说一句,我知道POJO是一个“普通的旧Java对象”,但您所说的“或人”是什么意思?@iX3:请原谅我的拼写。更正。没问题,请原谅我缺乏足够的Java经验,无法理解您可能在谈论地图:)