[英]Proper way to shutdown Apache httpcomponents blocking HTTP server
I have application with Apache HttpComponents 4.4.1 synchronous server , which runs several HTTP "services", for each of them I start HTTP server on different port. 我有Apache HttpComponents 4.4.1 同步服务器的应用程序,它运行几个HTTP“服务”,每个我在不同的端口启动HTTP服务器。 When the user decides to stop the service, I shut down HTTP server running on this port with this code:
当用户决定停止服务时,我使用以下代码关闭在此端口上运行的HTTP服务器:
org.apache.http.impl.bootstrap.HttpServer server;
....
public void stopServer(){
server.shutdown(42, TimeUnit.MICROSECONDS);
}
I have the following problem on Linux: If there are Keep-alive connections opened (there is no request processing), these sockets are not closed. 我在Linux上遇到以下问题:如果打开了Keep-alive连接(没有请求处理),则不会关闭这些套接字。 Only ServerSocket is closed:
仅关闭ServerSocket:
netstat -aon | grep 58276
TCP 127.0.0.1:50658 127.0.0.1:58276 ESTABLISHED 18012
TCP 127.0.0.1:58276 127.0.0.1:50658 ESTABLISHED 18012
In attempt to start again HTTP server on the same port a BindingException is thrown: 尝试在同一端口上再次启动HTTP服务器时抛出BindingException:
Caused by: java.net.BindException: Address already in use
at java.net.PlainSocketImpl.socketBind(Native Method)
at java.net.PlainSocketImpl.socketBind(PlainSocketImpl.java:521)
at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:414)
at java.net.ServerSocket.bind(ServerSocket.java:326)
at java.net.ServerSocket.<init>(ServerSocket.java:192)
at javax.net.DefaultServerSocketFactory.createServerSocket(ServerSocketFactory.java:170)
at org.apache.http.impl.bootstrap.HttpServer.start(HttpServer.java:116)
On Windows the behavior is the same , however there is no BindingException and the server starts process requests without any problems. 在Windows上,行为是相同的,但是没有BindingException,服务器启动进程请求没有任何问题。
Turns out to be a bug: https://issues.apache.org/jira/browse/HTTPCORE-420 oleg has already proposed a fix. 结果证明是一个错误: https: //issues.apache.org/jira/browse/HTTPCORE-420 oleg已经提出修复。 I will update this when it is released officially.
我将在正式发布时更新此信息。
Your problem is that connection is not closed. 您的问题是连接未关闭。 The HTTP specification does not specify how long a persistent connection should be kept alive.
HTTP规范没有规定持久连接应该保持多长时间。
From documentation : 来自文档 :
Some HTTP servers use a non-standard
Keep-Alive
header to communicate to the client the period of time in seconds they intend to keep the connection alive on the server side.某些HTTP服务器使用非标准的
Keep-Alive
标头与客户端通信他们打算在服务器端保持连接活动的时间段(以秒为单位)。HttpClient
makes use of this information if available.如果可用,
HttpClient
会使用此信息。 If theKeep-Alive
header is not present in the response,HttpClient
assumes the connection can be kept alive indefinitely.如果响应中不存在
Keep-Alive
标头,HttpClient
假定连接可以无限期保持活动状态。
So they advise to create your KeepAliveStrategy
in order to terminate those connections after certain time: 所以他们建议创建你的
KeepAliveStrategy
,以便在一定时间后终止这些连接:
ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
// Honor 'keep-alive' header
HeaderElementIterator it = new BasicHeaderElementIterator(
response.headerIterator(HTTP.CONN_KEEP_ALIVE));
while (it.hasNext()) {
HeaderElement he = it.nextElement();
String param = he.getName();
String value = he.getValue();
if (value != null && param.equalsIgnoreCase("timeout")) {
try {
return Long.parseLong(value) * 1000;
} catch(NumberFormatException ignore) {
}
}
}
HttpHost target = (HttpHost) context.getAttribute(
HttpClientContext.HTTP_TARGET_HOST);
if ("www.naughty-server.com".equalsIgnoreCase(target.getHostName())) {
// Keep alive for 5 seconds only
return 5 * 1000;
} else {
// otherwise keep alive for 30 seconds
return 30 * 1000;
}
}
};
CloseableHttpClient client = HttpClients.custom()
.setKeepAliveStrategy(myStrategy)
.build();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.