实现 HTTP 连接池的正确方法

ng.*_*bie 3 java connection-pooling resttemplate apache-httpclient-4.x

在调用某些 Web 服务的 REST API 期间,我使用 Apache HTTP 客户端进行连接池。

奇怪的是,尽管我使用了 HTTP 连接池,但我的性能并没有提高。

我正在使用Apache HTTP 客户端连接到我的 Web 服务,代码如下来自文档:

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();

cm.setMaxTotal(200);

cm.setDefaultMaxPerRoute(20);

HttpHost host = new HttpHost("abc.com", 80);
cm.setMaxPerRoute(new HttpRoute(host), 50);

CloseableHttpClient httpClient = HttpClients.custom()
        .setConnectionManager(cm)
        .build();
Run Code Online (Sandbox Code Playgroud)

我正在使用 SpringRestTemplate来包装HttpClient使用 Spring 的 Apache的实现HttpComponentsClientHttpRequestFactory。

但即使我不使用连接池,即。使用SimpleClientHttpRequestFactorySpring,我没有得到性能优势。

我的连接仍然需要相同的时间才能完成。

我所做的是实现 HTTP 连接池的正确方法吗?难道我做错了什么?

请让我知道是否需要我方提供更多信息。

Lui*_*ñoz 7

请注意 HTTP 客户端池的工作方式,它可能会在短时间内提高性能。检查下面的分析:

来自 PoolingHttpClientConnectionManager javadocs

旧连接的处理在 4.4 版中发生了变化。以前,代码会默认检查每个连接,然后再重新使用它。如果自上次使用连接以来经过的时间超过已设置的超时,代码现在只检查连接。默认超时设置为 2000 毫秒

从池性能的角度来看,这意味着只要管理器在默认情况下在 2 秒的时间内将该路由视为“活动”,就会重用与特定路由的连接。
到该路由的非活动连接 2 秒后将被视为陈旧并被丢弃,从而在下次请求该路由时导致连接初始化惩罚。

换句话说,开箱即用,池在 2 秒内提高了第一个连接之后的性能。重型路线是最受益的。

作为一个简单的测试,将池大小设置为一个较小的值,例如最大 5。在 linux 上发送 5 个请求并检查到该路由的已建立连接数

watch "netstat -ant | grep <your route IP>"

您应该看到 5 个连接。等待 10 或 20 秒,然后向同一路由发送 2 个请求,您应该看到这 5 个连接已关闭并创建了 2 个新连接。也可以通过调试日志来观察。这是一篇很好的文章作为参考。
有关http 日志记录的Apache 官方文档。


小智 1

我相信您正确设置了HttpClient池管理器。

我的实现有一个细微的差别HttpClients.custom(),我不是使用而是使用HttpClientBuilder.create(),但随后具有与您相同的方法调用。根据另一个 Stack Overflow答案,这应该没有什么区别。

我之前在 Spring 应用程序中使用过此配置,并获得了很好的好处。我想知道响应是否发生得足够快,以至于您没有看到很大的好处?我唯一能想到的另一件事是是否可能RestTemplate没有正确配置。