2

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

futureRequestExecutionService 的构造函数采用任何现有的 httpClient 实例和一个 ExecutorService 实例。配置两者时,将最大连接数与要使用的线程数保持一致很重要。当线程多于连接时,连接可能会因为没有可用连接而开始超时。当连接数多于线程数时,futureRequestExecutionService 不会使用所有连接数。

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

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

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

编辑:为了澄清,该HttpClient实例是使用一个HttpClientBuilder为其PoolingHttpClientConnectionManager连接管理器设置的。但是,这不会发生在与 and 的创建相同的范围PoolingHttpClientConnectionManagerFutureRequestExecutionService。我开始怀疑它们应该一起创建,然后HttpClient使用实例而不是传递FutureRequestExecutionService实例。

4

2 回答 2

7

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

说了这么多,要回答你的问题,我不建议紧密耦合PoolingHttpClientConnectionManagerFutureRequestExecutionService接线代码。对我来说,更好的方法应该是使用一个简单的 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-26T09:43:49.417 回答
0

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

apache here也提供了一个示例。

于 2013-09-25T21:46:36.730 回答