【发布时间】:2015-03-23 15:40:08
【问题描述】:
在对我们基于 Java 的中间件通过 Java 客户端 API 访问 MarkLogic 服务器进行压力测试后,我在无法打开更多 HTTP 连接并发生死锁情况的情况下运行。我正在使用一个DatabaseClient 共享实例,但在每个请求上创建一个JSONDocumentManager(带有一个JacksonHandle 用于阅读,没有处理特定的关闭问题)。可能存在连接未正确关闭的问题,还是我必须自己处理?
通过查看无法处理更多连接的netstat,我确实看到FIN_WAIT_2 中有109 个到MarkLogic 服务器(在localhost:8040 上运行)的连接:
ffffff8045f765a0 31c91c01 tcp4 0 0 localhost.8040 localhost.65396 FIN_WAIT_2
和CLOSE_WAIT 中相同数量 (109) 的 TCP 连接:
ffffff804ff83400 73965e73 tcp4 0 0 localhost.49286 localhost.8040 CLOSE_WAIT
我正在使用带有 Java 1.7 (Mac OSX 10.9.5) 和 MarkLogic 客户端 API 2.0.4 的 MarkLogic 服务器 7.0.4。这是线程转储的第一部分(有 10 个类似的线程似乎在等待服务器响应):
"http-nio-8080-exec-10" #31 daemon prio=5 os_prio=31 tid=0x00007fc61f344000 nid=0x7c03 waiting on condition [0x00000001265bb000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000007a59cfff8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
at org.apache.http.impl.conn.tsccm.WaitingThread.await(WaitingThread.java:159)
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute.getEntryBlocking(ConnPoolByRoute.java:398)
at org.apache.http.impl.conn.tsccm.ConnPoolByRoute$1.getPoolEntry(ConnPoolByRoute.java:298)
at org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager$1.getConnection(ThreadSafeClientConnManager.java:238)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:423)
at org.apache.http.impl.client.AbstractHttpClient.doExecute(AbstractHttpClient.java:863)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:115)
at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:57)
at com.sun.jersey.client.apache4.ApacheHttpClient4Handler.handle(ApacheHttpClient4Handler.java:170)
at com.marklogic.client.impl.DigestChallengeFilter.handle(DigestChallengeFilter.java:34)
at com.sun.jersey.api.client.filter.HTTPDigestAuthFilter.handle(HTTPDigestAuthFilter.java:493)
at com.sun.jersey.api.client.Client.handle(Client.java:648)
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:680)
at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.get(WebResource.java:507)
at com.marklogic.client.impl.JerseyServices.getDocumentImpl(JerseyServices.java:612)
at com.marklogic.client.impl.JerseyServices.getDocument(JerseyServices.java:568)
at com.marklogic.client.impl.DocumentManagerImpl.read(DocumentManagerImpl.java:270)
at com.marklogic.client.impl.DocumentManagerImpl.read(DocumentManagerImpl.java:204)
at com.marklogic.client.impl.DocumentManagerImpl.read(DocumentManagerImpl.java:164)
at com.acme.dashboard.service.ReportMetadataRepository.getByName(ReportMetadataRepository.java:64)
为了更好的可读性,省略了堆栈跟踪的更多细节。 在查看 JerseyServices 之后,我还尝试调整以下系统属性(不幸的是没有任何改进):
com.marklogic.client.maximumRetrySeconds: 3 (default: 120)
com.marklogic.client.minimumRetries: 3 (default: 8)
【问题讨论】:
-
netstat 显示什么?
-
@EJP 大约 220 个连接(其中一半处于状态
FIN_WAIT_2,另一半处于CLOSE_WAIT,请参阅我的第二和第三段;) -
你能分享你传递给 JSONDocumentManager.read 的句柄吗?如果它是流式句柄(带有 close() 方法的句柄),您需要确保在完成后关闭句柄。
-
您是否面临死锁场景?例如,如果请求停止,线程是否永远不会完成?还是您只是向我们展示了许多并发请求期间的快照?
-
@SamMefford 我正在使用
JacksonHandle和TuplesHandle,它们似乎都没有可用的关闭方法。是的,我遇到了僵局(让我在我的问题中澄清这一点)。谢谢。
标签: java multithreading jersey marklogic jersey-client