Java:由 HTTP 连接创建的等待连接线程存活时间很长
Java: Waiting connection threads created by HTTP connection are alive for very long duration
我有一个服务器端代码,用于检查 SOAP 服务是否启动。代码如下:
String response = "";
while (response.length() == 0) {
try {
final URL url = new URL("DummySoapServiceURL");
final HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = null;
try {
httpConnection.setRequestMethod("GET");
inputStream = httpConnection.getInputStream();
final byte[] buffer = new byte[BUFFER_SIZE];
while (inputStream.read(buffer, 0, BUFFER_SIZE) != -1) {
response = new String(buffer);
}
} finally {
IOUtils.closeQuietly(inputStream);
httpConnection.disconnect();
}
} catch (MalformedURLException e) {
// error handling
} catch (IOException e) {
// error handling
}
}
现在的问题是,每次检查都会创建大约 3-4 个连接线程。即使 SOAP 服务检查完成,这些线程仍然存在。线程转储的快照,这些线程看起来像:
"http-host/ip:port-11" prio=10 tid=0x00000000064f0000 nid=0x32cc waiting on condition [0x00002b54bc604000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d5093c78> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.net.NioEndpoint$DefaultThreadFactory.run(NioEndpoint.java:1249)
at java.lang.Thread.run(Thread.java:744)
Locked ownable synchronizers:
- None
现在我不确定为什么这些连接线程是 waiting/parking 以及如何关闭它们。在我的代码中,打开的流被关闭并使用 disconnect() 断开连接。
我还尝试设置以下 HTTP 属性:
httpConnection.addRequestProperty("Connection", "close");
但这并没有帮助。我怀疑 JAVA 可能会在某个时候关闭这些线程。但我不知道,何时以及如何? JDK版本为jdk1.7.0_51_x64。请让我知道,如何阻止这些连接线程数的增加?
迁移了整个实现以使用 apache HTTP 客户端,因为它具有特殊的 API 以实现更好的控制。但这没有帮助。即使使用 apache HTTP 客户端,我也能看到这些等待的连接线程。
终于在 redhat website for JBOSS HTTP connector configuration 上找到了提示。为 HTTP 连接器配置线程池并解决了问题:
<subsystem xmlns="urn:jboss:domain:threads:1.1">
<thread-factory name="http-connector-factory" group-name="uq-thread-pool" thread-name-pattern="HTTP-%t" priority="9"/>
<unbounded-queue-thread-pool name="uq-thread-pool">
<max-threads count="5"/>
<keepalive-time time="5" unit="seconds"/>
<thread-factory name="http-connector-factory"/>
</unbounded-queue-thread-pool>
</subsystem>
<subsystem xmlns="urn:jboss:domain:web:2.2" default-virtual-server="default-host" native="false">
<connector name="http" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="http" socket-binding="http" executor="uq-thread-pool"/>
....
....
我有一个服务器端代码,用于检查 SOAP 服务是否启动。代码如下:
String response = "";
while (response.length() == 0) {
try {
final URL url = new URL("DummySoapServiceURL");
final HttpURLConnection httpConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = null;
try {
httpConnection.setRequestMethod("GET");
inputStream = httpConnection.getInputStream();
final byte[] buffer = new byte[BUFFER_SIZE];
while (inputStream.read(buffer, 0, BUFFER_SIZE) != -1) {
response = new String(buffer);
}
} finally {
IOUtils.closeQuietly(inputStream);
httpConnection.disconnect();
}
} catch (MalformedURLException e) {
// error handling
} catch (IOException e) {
// error handling
}
}
现在的问题是,每次检查都会创建大约 3-4 个连接线程。即使 SOAP 服务检查完成,这些线程仍然存在。线程转储的快照,这些线程看起来像:
"http-host/ip:port-11" prio=10 tid=0x00000000064f0000 nid=0x32cc waiting on condition [0x00002b54bc604000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d5093c78> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.net.NioEndpoint$DefaultThreadFactory.run(NioEndpoint.java:1249)
at java.lang.Thread.run(Thread.java:744)
Locked ownable synchronizers:
- None
现在我不确定为什么这些连接线程是 waiting/parking 以及如何关闭它们。在我的代码中,打开的流被关闭并使用 disconnect() 断开连接。
我还尝试设置以下 HTTP 属性:
httpConnection.addRequestProperty("Connection", "close");
但这并没有帮助。我怀疑 JAVA 可能会在某个时候关闭这些线程。但我不知道,何时以及如何? JDK版本为jdk1.7.0_51_x64。请让我知道,如何阻止这些连接线程数的增加?
迁移了整个实现以使用 apache HTTP 客户端,因为它具有特殊的 API 以实现更好的控制。但这没有帮助。即使使用 apache HTTP 客户端,我也能看到这些等待的连接线程。
终于在 redhat website for JBOSS HTTP connector configuration 上找到了提示。为 HTTP 连接器配置线程池并解决了问题:
<subsystem xmlns="urn:jboss:domain:threads:1.1">
<thread-factory name="http-connector-factory" group-name="uq-thread-pool" thread-name-pattern="HTTP-%t" priority="9"/>
<unbounded-queue-thread-pool name="uq-thread-pool">
<max-threads count="5"/>
<keepalive-time time="5" unit="seconds"/>
<thread-factory name="http-connector-factory"/>
</unbounded-queue-thread-pool>
</subsystem>
<subsystem xmlns="urn:jboss:domain:web:2.2" default-virtual-server="default-host" native="false">
<connector name="http" protocol="org.apache.coyote.http11.Http11NioProtocol" scheme="http" socket-binding="http" executor="uq-thread-pool"/>
....
....