java线程挂起,导致线程池资源耗尽,服务器响应缓慢

吐槽的达达仔 发布于 2014/12/02 13:31
阅读 6K+
收藏 0

Thread Dump如下:

"http-8080-147" daemon prio=10 tid=0x00007fb970216000 nid=0x3792 waiting on condition [0x00007fb7ecfcd000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x000000073e4e0000> (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 org.apache.http.pool.PoolEntryFuture.await(PoolEntryFuture.java:133)
        at org.apache.http.pool.AbstractConnPool.getPoolEntryBlocking(AbstractConnPool.java:282)
        at org.apache.http.pool.AbstractConnPool.access$000(AbstractConnPool.java:64)
        at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:177)
        at org.apache.http.pool.AbstractConnPool$2.getPoolEntry(AbstractConnPool.java:170)
        at org.apache.http.pool.PoolEntryFuture.get(PoolEntryFuture.java:102)
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.leaseConnection(PoolingHttpClientConnectionManager.java:244)
        at org.apache.http.impl.conn.PoolingHttpClientConnectionManager$1.get(PoolingHttpClientConnectionManager.java:231)
        at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:173)
        at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:195)
        at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:86)
        at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:108)
        at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:184)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:82)
        at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:106)
        at com.mailu.re.commons.http.NewHttpClientHelper.doGet(NewHttpClientHelper.java:80)



其本质是Servlet调用HttpClient对Solr进行访问。

Solr访问网络没有问题,JDK1.7,Linux ulimit 8K

CPU,内存正常。

有6台服务器部署了一样的代码,有一台不会阻塞,配置都是一样的。


请各位大大帮忙指点




以下是问题补充:

@吐槽的达达仔:另外,本人在每次调用solr的HttpClient的过程中, 加入了Thread.sleep(50); 异常解除。。 真是 百思不得其解~~ (2014/12/03 13:21)
加载中
1
zfc827
zfc827

你理解的异步是客户端的哦,我说的是服务端的异步,HTTP1.1的重要改进就是允许浏览器和服务器保持一个长连接,而不是请求完就马上返回,这就让Servlet3.0规范中新加入了一个异步上下文接口 AsyncContext

通过 request#startAsync() 方法开启上下文,并注册相关监听,这样能做到即时释放 Servlet 线程,对于改善因耗时任务引发的 Servet 容器线程池被大量阻塞很有帮助。下面是一个例子,你可以参考一下。

0
吐槽的达达仔
吐槽的达达仔
自己给自己顶一个。。求高手啊。。搞了3天都搞不出结果来。。。
0
杨三更
杨三更
贴上来的东西还是少。。。,建议增加个超时失败 应该会有改善
0
吐槽的达达仔
吐槽的达达仔

引用来自“杨三更”的评论

贴上来的东西还是少。。。,建议增加个超时失败 应该会有改善

谢谢回复。

其实是Servlet里面调了个HttpClient的接口。后来做了修改,原本一个线程调一次,变成一个线程调多次,结果就会发生阻塞了。HttpClient换了几个版本都不行。。真的好奇怪。。超时也加上去了,仍让阻塞。

请问大大还有啥好的建议。

0
zfc827
zfc827
这个线程池是 Servlet 容器的线程池还是 HttpClient 的?
吐槽的达达仔
吐槽的达达仔
@zfc827 系统要求是实时响应。。。异步适用于图片获取,Email发送等。。
zfc827
zfc827
回复 @吐槽的达达仔 : 如果你用的是Servlet 3.0,应该考虑用异步请求处理耗时长的工作,释放tomcat线程。如果不是,就应当自己实现异步。
吐槽的达达仔
吐槽的达达仔
是Tomcat的满了,最多我看到有500个,阻塞在HttpClient那里。。
0
duty
duty
把整个dump发出来比较好分析。
0
char1st
char1st

修改连接池的参数吧。

http://jinnianshilongnian.iteye.com/blog/2089792

另外为什么要直接用HttpClient来调用solr,而不选择 solr4j呢?




吐槽的达达仔
吐槽的达达仔
历史遗留原因,你懂的。。。
0
朱宏青
朱宏青
http://www.oschina.net/p/unirest
0
吐槽的达达仔
吐槽的达达仔

引用来自“zfc827”的评论

你理解的异步是客户端的哦,我说的是服务端的异步,HTTP1.1的重要改进就是允许浏览器和服务器保持一个长连接,而不是请求完就马上返回,这就让Servlet3.0规范中新加入了一个异步上下文接口 AsyncContext

通过 request#startAsync() 方法开启上下文,并注册相关监听,这样能做到即时释放 Servlet 线程,对于改善因耗时任务引发的 Servet 容器线程池被大量阻塞很有帮助。下面是一个例子,你可以参考一下。

也就是servlet的线程已经走完并释放,然后链接挂起。

当运行结束后,通过链接返回信息。

这个确实颠覆了我对servlet的理解,不过毕竟是老代码,只能先将就着改了。


0
shuaia
shuaia
你先判断下是solr服务器不允许建立连接,还是部署servlet的服务器无法建立更多了解。比如打开句柄受限,连接过多未释放什么的。。。把确定没有问题的地方排除掉,逐步缩小包围圈。。。
返回顶部
顶部