Java/jetty在一段时间的重载后不会响应连接

Java/jetty在一段时间的重载后不会响应连接,java,ubuntu,amazon-ec2,jetty,Java,Ubuntu,Amazon Ec2,Jetty,我们在Jetty下运行的Javaservlet遇到了一个非常棘手的问题。当负载从低到中等时,它工作得非常好,但当负载达到一定水平时,它将在大约10-20分钟后停止响应请求 如果我们在使用curl连接时跟踪主java进程,我们可以看到它建立连接、接收请求、解析请求并执行它通常执行的操作(查询Solr服务器、执行一些MySQL查询等),但结果永远不会发送回客户机 当它挂起时,它将无限期地挂起。没有多少时间会让它“突然跳出”,但是如果我们在主java/jetty进程下杀死任何随机线程,线程的数量就会减

我们在Jetty下运行的Javaservlet遇到了一个非常棘手的问题。当负载从低到中等时,它工作得非常好,但当负载达到一定水平时,它将在大约10-20分钟后停止响应请求

如果我们在使用curl连接时跟踪主java进程,我们可以看到它建立连接、接收请求、解析请求并执行它通常执行的操作(查询Solr服务器、执行一些MySQL查询等),但结果永远不会发送回客户机

当它挂起时,它将无限期地挂起。没有多少时间会让它“突然跳出”,但是如果我们在主java/jetty进程下杀死任何随机线程,线程的数量就会减少,它会再次开始响应请求

下面是它的外观:

# curl http://localhost:8080/some-servlet-url

(Does not respond at this point)

# ps -efL | grep qserv | wc -l
243
# ps -efL | grep qserv | wc -l
243
# ps -efL | grep qserv | wc -l
243

(Number of threads remain seemingly constant)

# kill 29760   <--- random thread under the main java/jetty process
# ps -efL | grep qserv | wc -l
26

(Number of threads immediately decreases sharply)

# curl http://localhost:8080/some-servlet-url
... HTTP response ...

(Responds to connections again)
我们已经尝试了几种不同的java和Jetty版本。我们还尝试使用Tomcat代替Jetty——同样的问题

使用YourKit评测应用程序时,不会显示明显的线程锁定或CPU过度使用

有什么想法吗

编辑:我们能够获得挂起的java进程的堆栈跟踪,看起来所有http线程都处于这种状态:

"http-bio-8080-exec-5" daemon prio=10 tid=0x00007fe518007800 nid=0x1fc5 in Object.wait() [0x00007fe57934f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076ee9d230> (a org.apache.commons.pool.impl.GenericObjectPool)
        at java.lang.Object.wait(Object.java:503)
        at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:810)
        - locked <0x000000076ee9d230> (a org.apache.commons.pool.impl.GenericObjectPool)
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
        at net.acmecorp.active.QueryResultXMLFormatter.selectBestHitsAndRunDocumentCompletion(QueryResultXMLFormatter.java:362)
        at net.acmecorp.active.QueryResultXMLFormatter.queryResultToXMLRootElement(QueryResultXMLFormatter.java:167)
        at net.acmecorp.active.QueryPrepareAndExecuter.prepareParametersAndExecuteQuery_AndInvokeFormatter(QueryPrepareAndExecuter.java:239)
        at net.acmecorp.servlets.MultiQueryServlet.handle(MultiQueryServlet.java:470)
        at net.acmecorp.servlets.MultiQueryServlet.doGet(MultiQueryServlet.java:85)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        - locked <0x0000000700dd70d0> (a org.apache.tomcat.util.net.SocketWrapper)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
        at java.lang.Thread.run(Thread.java:722)

   Locked ownable synchronizers:
        - <0x000000076ed40990> (a java.util.concurrent.ThreadPoolExecutor$Worker)
对象中的“http-bio-8080-exec-5”守护进程prio=10 tid=0x00007fe518007800 nid=0x1fc5.wait()[0x00007fe57934f000]
java.lang.Thread.State:正在等待(在对象监视器上)
在java.lang.Object.wait(本机方法)
-等待(org.apache.commons.pool.impl.GenericObject池)
等待(Object.java:503)
位于org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:810)
-锁定(org.apache.commons.pool.impl.GenericObject池)
位于org.apache.commons.dbcp.poolgDataSource.getConnection(poolgDataSource.java:95)
在net.acmecorp.active.QueryResultXMLFormatter.selectBestHit和RunDocumentCompletion(QueryResultXMLFormatter.java:362)
位于net.acmecorp.active.QueryResultXMLFormatter.queryResultToXMLRootElement(QueryResultXMLFormatter.java:167)
在net.acmecorp.active.QueryPrepareAndExecuter.prepareParametersAndExecuteQuery_和InVokeFormatter(QueryPrepareAndExecuter.java:239)上
位于net.acmecorp.servlets.MultiQueryServlet.handle(MultiQueryServlet.java:470)
位于net.acmecorp.servlets.MultiQueryServlet.doGet(MultiQueryServlet.java:85)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
位于javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
位于org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
位于org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
位于org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
位于org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
位于org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
位于org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
位于org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
位于org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
位于org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
位于org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
位于org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
位于org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
位于org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
-锁定(org.apache.tomcat.util.net.SocketWrapper)
位于java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
位于java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
运行(Thread.java:722)
锁定可拥有的同步器:
-(一个java.util.concurrent.ThreadPoolExecutor$Worker)

我自己也不是一个真正的java人,所以我不知道这里到底出了什么问题,但看起来他们都在等待着什么

您有数据库池问题,您的http线程都在等待数据库资源释放。这是一个常见的问题,您要么需要增加池中的数据库连接数,这样就不再是问题,要么需要使用QoS服务(如jetty中的QoSFilter)来限制进程进入的请求数,以保护小型数据库池

现在,您的数据库池被占用的原因可能有很多,您可能在应用程序中泄漏了它们(从池中获取它们,使用它们,并且永远不会返回它们),或者您可能只是同时收到了太多的请求。或者数据库池库本身存在问题,这种情况就会发生


无论如何,这不是jetty或tomcat问题,而是应用程序和数据库之间的资源争用问题。请求进入jetty或tomcat,进入servlet区域,然后在servlet或类似程序中等待数据库连接,就这么简单。

这听起来更像是应用程序的问题,而不是tomcat/jetty。它可能是一个正在创建的对象,而不是取消引用的对象,然后长时间的暂停是GC试图重新组织堆。当你杀死线程时,你将释放在该线程中分配的内存。@DanMatthews Grott,我同意这似乎是这样的,但我们已经打开了GC日志,无法看到GC和挂起之间的任何连接。另外,据我所知,GC会导致(有时是长时间的)暂停,但如果我们允许的话,这个过程会暂停几天。我相信你是对的。我没看见你
"http-bio-8080-exec-5" daemon prio=10 tid=0x00007fe518007800 nid=0x1fc5 in Object.wait() [0x00007fe57934f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x000000076ee9d230> (a org.apache.commons.pool.impl.GenericObjectPool)
        at java.lang.Object.wait(Object.java:503)
        at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:810)
        - locked <0x000000076ee9d230> (a org.apache.commons.pool.impl.GenericObjectPool)
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
        at net.acmecorp.active.QueryResultXMLFormatter.selectBestHitsAndRunDocumentCompletion(QueryResultXMLFormatter.java:362)
        at net.acmecorp.active.QueryResultXMLFormatter.queryResultToXMLRootElement(QueryResultXMLFormatter.java:167)
        at net.acmecorp.active.QueryPrepareAndExecuter.prepareParametersAndExecuteQuery_AndInvokeFormatter(QueryPrepareAndExecuter.java:239)
        at net.acmecorp.servlets.MultiQueryServlet.handle(MultiQueryServlet.java:470)
        at net.acmecorp.servlets.MultiQueryServlet.doGet(MultiQueryServlet.java:85)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
        at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
        at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
        - locked <0x0000000700dd70d0> (a org.apache.tomcat.util.net.SocketWrapper)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
        at java.lang.Thread.run(Thread.java:722)

   Locked ownable synchronizers:
        - <0x000000076ed40990> (a java.util.concurrent.ThreadPoolExecutor$Worker)