如何强制 Apache HttpClient / HttpConnection 绝对关闭 tcp 连接?
How to force Apache HttpClient / HttpConnection to absolutely close tcp connection?
我使用大量与 Apache HttpClient (org.apache.httpcomponents 4.3.6) 的 http 连接来测试服务器,我无法强制关闭连接,即使我将 HttpConnectionManager
安排到 httpClient.getConnectionManager().shutdown();
在另一个线程中 10 秒后。
httpClient.close()
也无济于事。
连接可以持续几分钟甚至几小时。
我试过自定义 SocketConfig
但这也无济于事:
SocketConfig socketConfig = SocketConfig.custom()
.setSoKeepAlive(false)
.setSoLinger(5)
.setSoReuseAddress(true)
.setSoTimeout(5000)
.setTcpNoDelay(true).build();
我获取内容的方式:
HttpUriRequest request = new HttpGet(url);
HttpResponse response = httpClient.execute(request);
try (InputStream in = response.getEntity().getContent()) {
String result = IOUtils.toString(in, StandardCharsets.UTF_8);
httpClient.close();
return result;
}
我构建 HTTP 客户端的方式:
SocketConfig socketConfig = SocketConfig.custom()
.setSoKeepAlive(false)
.setSoLinger(configuration.getInt("proxy.list.socket.so.linger"))
.setSoReuseAddress(true)
.setSoTimeout(configuration.getInt("proxy.list.socket.so.timeout"))
.setTcpNoDelay(true).build();
HttpClientBuilder builder = HttpClientBuilder.create();
builder.disableAutomaticRetries();
builder.disableContentCompression();
builder.disableCookieManagement();
builder.disableRedirectHandling();
builder.setConnectionReuseStrategy(new NoConnectionReuseStrategy());
builder.setDefaultSocketConfig(socketConfig);
我的关机原型之一:
shutdownExecutor.schedule(() -> {
httpClient.getConnectionManager().closeExpiredConnections();
httpClient.getConnectionManager().closeIdleConnections(1, TimeUnit.SECONDS);
httpClient.getConnectionManager().shutdown();
httpClient.notifyAll();
try {
httpClient.close();
} catch (IOException ex) {
}
}, configuration.getInt("proxy.test.forced.timeout.seconds"), TimeUnit.SECONDS);
String content = HttpContentFetcher.getAndCloseClient(url, httpClient);
RequestConfig
有帮助。现在看起来所有连接都在指定限制内被丢弃。
RequestConfig config= RequestConfig.custom()
.setCircularRedirectsAllowed(false)
.setConnectionRequestTimeout(4000)
.setConnectTimeout(4000)
.setMaxRedirects(0)
.setRedirectsEnabled(false)
.setSocketTimeout(4000)
.setStaleConnectionCheckEnabled(true).build();
request.setConfig(config);
我使用大量与 Apache HttpClient (org.apache.httpcomponents 4.3.6) 的 http 连接来测试服务器,我无法强制关闭连接,即使我将 HttpConnectionManager
安排到 httpClient.getConnectionManager().shutdown();
在另一个线程中 10 秒后。
httpClient.close()
也无济于事。
连接可以持续几分钟甚至几小时。
我试过自定义 SocketConfig
但这也无济于事:
SocketConfig socketConfig = SocketConfig.custom()
.setSoKeepAlive(false)
.setSoLinger(5)
.setSoReuseAddress(true)
.setSoTimeout(5000)
.setTcpNoDelay(true).build();
我获取内容的方式:
HttpUriRequest request = new HttpGet(url);
HttpResponse response = httpClient.execute(request);
try (InputStream in = response.getEntity().getContent()) {
String result = IOUtils.toString(in, StandardCharsets.UTF_8);
httpClient.close();
return result;
}
我构建 HTTP 客户端的方式:
SocketConfig socketConfig = SocketConfig.custom()
.setSoKeepAlive(false)
.setSoLinger(configuration.getInt("proxy.list.socket.so.linger"))
.setSoReuseAddress(true)
.setSoTimeout(configuration.getInt("proxy.list.socket.so.timeout"))
.setTcpNoDelay(true).build();
HttpClientBuilder builder = HttpClientBuilder.create();
builder.disableAutomaticRetries();
builder.disableContentCompression();
builder.disableCookieManagement();
builder.disableRedirectHandling();
builder.setConnectionReuseStrategy(new NoConnectionReuseStrategy());
builder.setDefaultSocketConfig(socketConfig);
我的关机原型之一:
shutdownExecutor.schedule(() -> {
httpClient.getConnectionManager().closeExpiredConnections();
httpClient.getConnectionManager().closeIdleConnections(1, TimeUnit.SECONDS);
httpClient.getConnectionManager().shutdown();
httpClient.notifyAll();
try {
httpClient.close();
} catch (IOException ex) {
}
}, configuration.getInt("proxy.test.forced.timeout.seconds"), TimeUnit.SECONDS);
String content = HttpContentFetcher.getAndCloseClient(url, httpClient);
RequestConfig
有帮助。现在看起来所有连接都在指定限制内被丢弃。
RequestConfig config= RequestConfig.custom()
.setCircularRedirectsAllowed(false)
.setConnectionRequestTimeout(4000)
.setConnectTimeout(4000)
.setMaxRedirects(0)
.setRedirectsEnabled(false)
.setSocketTimeout(4000)
.setStaleConnectionCheckEnabled(true).build();
request.setConfig(config);