在对通过Java客户端API访问MarkLogic服务器的基于Java的中间件进行了一些压力测试之后,我遇到了无法再打开HTTP连接且出现死锁的情况。我正在使用一个DatabaseClient
共享实例,但是在每个请求上创建一个JSONDocumentManager
(带有JacksonHandle
用于读取,没有处理任何特定的关闭关注)。可能存在连接未正确关闭的问题,还是我必须自己照顾?
通过查看无法处理更多连接的点的netstat
,我确实看到到localhost:8040
中与MarkLogic服务器(在FIN_WAIT_2
上运行)的109个连接:
ffffff8045f765a0 31c91c01 tcp4 0 0 localhost.8040 localhost.65396 FIN_WAIT_2
和
CLOSE_WAIT
中相同数目的TCP连接(109):ffffff804ff83400 73965e73 tcp4 0 0 localhost.49286 localhost.8040 CLOSE_WAIT
我正在将MarkLogic服务器7.0.4与Java 1.7(Mac OSX 10.9.5)和MarkLogic客户端API 2.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)
最佳答案
听起来您可能遇到了JacksonHandle和TuplesHandle没有关闭它们的连接的错误(github问题#89)。此问题已在Java Client API 2.0.5中修复。您是否可以在ML Server的7.0-5实例上运行测试并使用Java客户端API的2.0.5版本?