PoolingHttpClientConnectionManager不重用现有的空闲连接

时间:2017-07-20 12:28:19

标签: httpclient apache-httpclient-4.x

我正在使用Apache PoolingHttpClientConnectionManager来创建一个conenctions池。但是我在日志中看到现有的Idle连接没有被使用,而是创建了一个新的连接。以下是代码

PoolingHttpClientConnectionManager connManager = connManager = new PoolingHttpClientConnectionManager();
connManager.setMaxTotal(4);
    connManager.setDefaultMaxPerRoute(4);

//Creating CloseableHttpClient with a default keep alive of 2 minutes
    CloseableHttpClient  client = HttpClients.custom()
            .setConnectionManager(connManager)
            .setKeepAliveStrategy(new KeepAliveStrategy(keepAlive))
            .build();


//Sending 1st request
String xml="<xml data>";
HttpPost post = new HttpPost("<URL>");
    HttpEntity entity = new ByteArrayEntity(xml.getBytes("UTF-8"));
    post.setEntity(entity);
    HttpResponse  response =client.execute(post);
    String result = EntityUtils.toString(response.getEntity());
    EntityUtils.consume(response.getEntity());

收到回复后, PoolStats 表示可用连接总数为1

现在我再次在5秒后触发相同的请求,并在收到响应后 PoolStats 表明可用连接总数为2

以下代码适用于 PoolStats

 PoolStats stats = connManager.getTotalStats();
    System.out.println("Total Connections Available : "+stats.getAvailable());
  

我的问题是,在第一次请求响应之后,池中已经有一个连接,所以为什么它再创建一个连接。为什么它没有使用现有的连接?

1 个答案:

答案 0 :(得分:1)

问题是因为我在这里使用SSL所以默认情况下不允许SSL上下文共享同一个连接。这就是它为每个请求创建另一个连接的原因。该解决方案创建自定义UserTokenHandler并将其分配给Connection Manager。

UserTokenHandler userTokenHandler = new UserTokenHandler() {

        @Override
        public Object getUserToken(final HttpContext context) {
            return context.getAttribute("my-token");
        }

    };

client = HttpClients.custom()
            .setConnectionManager(connManager)
            .setUserTokenHandler(userTokenHandler)
            .setKeepAliveStrategy(new KeepAliveStrategy(keepAlive))
            .build();