BasicHttpClientConnectionManager

BasicHttpClientConnectionManager

我最近从java.net切换到org.apache.http.client,并且已经使用ClosableHttpClient设置了HttpClientBuilder。作为连接管理器,我正在使用BasicHttpClientConnectionManager

现在我遇到的问题是,当我创建一些HTTP请求时,经常会遇到超时异常。似乎连接管理器正在保持连接打开以重用它们,但是如果系统空闲几分钟,则此连接将超时,当我发出下一个请求时,我得到的第一件事就是超时。然后再重复一次相同的请求通常可以正常工作。

有没有一种方法可以配置BasicHttpClientConnectionManager以便不重用其连接并每次都创建一个新连接?

最佳答案

有几种解决问题的方法


不再需要空闲的连接。下面的代码通过在每次HTTP交换之后关闭持久连接来有效地禁用连接持久性。

BasicHttpClientConnectionManager cm = new BasicHttpClientConnectionManager();
CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(cm).build();
...
try (CloseableHttpResponse response = httpclient.execute(new HttpGet("/"))) {
    System.out.println(response.getStatusLine());
    EntityUtils.consume(response.getEntity());
}
cm.closeIdleConnections(0, TimeUnit.MILLISECONDS);

将连接保持活动时间限制在相对较小的范围内

BasicHttpClientConnectionManager cm = new BasicHttpClientConnectionManager();
CloseableHttpClient httpclient = HttpClients.custom()
        .setConnectionManager(cm)
        .setKeepAliveStrategy((response, context) -> 1000)
        .build();
try (CloseableHttpResponse response = httpclient.execute(new HttpGet("/"))) {
    System.out.println(response.getStatusLine());
    EntityUtils.consume(response.getEntity());
}

(推荐)使用池连接管理器并将连接总时间设置为有限值。与使用池连接相比,使用基本连接管理器没有任何好处,除非期望您的代码在EJB容器中运行。

CloseableHttpClient httpclient = HttpClients.custom()
        .setConnectionTimeToLive(5, TimeUnit.SECONDS)
        .build();
try (CloseableHttpResponse response = httpclient.execute(new HttpGet("/"))) {
    System.out.println(response.getStatusLine());
    EntityUtils.consume(response.getEntity());
}

10-08 17:05