我最近从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());
}