我正在访问Tomcat 8.5 Web服务器的Java“客户端”中进行性能测试。在大约13,000个请求之后,HTTP请求失败并显示错误,
org.apache.http.impl.client.DefaultHttpClient tryConnect
INFO: Retrying connect
java.net.BindException: Address already in use: connect
at java.net.DualStackPlainSocketImpl.waitForConnect(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at org.apache.http.conn.scheme.PlainSocketFactory.connectSocket(PlainSocketFactory.java:127)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180)
at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:294)
at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:643)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:479)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:784)
代码是,
for (int i = 0; i < 15000; i++) {
try {
if (i % 1000 == 0) System.out.println("Iterations: " + Integer.toString(i));
HttpGet request = new HttpGet("http://localhost:9080");
DefaultHttpClient client = new DefaultHttpClient();
HttpResponse response = client.execute(request, new BasicHttpContext());
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Iterations: " + Integer.toString(i));
System.exit(1);
}
}
如果我缓存DefaultHttpClient,则不会发生此错误。也尝试过,
request.releaseConnection();
client.getConnectionManager().shutdown();
但不会更改错误。该错误似乎不是由客户端引起的。如果我可以通过URL访问另一个网站,则可以。似乎是由Windows中的Tomcat耗尽了文件句柄或套接字资源等引起的。如果我在崩溃后立即将其作为另一个进程再次运行,它将在1次运行中失败,而不是13,000次,因此问题是Tomcat资源不足。似乎DefaultHttpClient没有关闭其连接,或者Tomcat在出现gc之前没有释放其连接。
任何想法为什么会发生或如何解决?
似乎您使用的是错误的方式使用HttpClient(例如,可能会复制粘贴旧的旧代码段)
即
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(cm)
.build();
HttpContext context = HttpClientContext.create();
try {
final HttpGet request = new HttpGet("http://localhost:9080");
for(int i = 0; i < 15000; i++) {
CloseableHttpResponse response = httpClient.execute(request, context);
try {
HttpEntity entity = response.getEntity();
EntityUtils.consume(entity);
} finally {
response.close();
}
}
} finally {
client.close();
}
}