为什么tomcat占用cpu这么高,请帮忙分析

恺哥 发布于 2011/12/30 08:52
阅读 22K+
收藏 41

有这样一台web服务器,上边安装着nginx(做反向代理),另外安装了一个tomcat7.0.23,jdk1.7

该tomcat上运行了一个webapp,主要提供了两个服务,一个是短信,另一个是定时器,定时获取邮件表中未发送的邮件,每分钟检查一次

该webapp部署在别的服务器上,cpu,内存工作都正常,唯独部署在这台服务器上,cpu高的吓人;

下图是我用visualVM抓的图,请帮忙分析一下

 

把问题服务器上的环境原封不动的复制到另外一台机器上,工作十分正常

另外,该服务2个月前已经稳定运行了1年半,tomcat都没重启过,就是最近突然出现这个问题,cpu 接近100%

起初考虑是否该tomcat的某个端口收到了攻击,我将tomcat的端口折腾了一边,问题依旧

请大家帮忙分析一下

加载中
3
红薯
红薯

我以前经常碰到这种问题,一般我会做一个简单的jsp页面,列举虚拟机中所有的线程(显示线程名称、对应类名以及运行状态),然后监控看看是否有一些线程是一直处于RUNNABLE状态(除了一些Tomcat自身的服务线程除外)

继续深入来看的话,在接收到请求的时候把当前线程名和对应的URL地址打印出来。

二者结合来看,就能看到是用户在访问哪个URL而导致的线程一直在运行。

恺哥
恺哥
感谢您的提示,为我解决此问题节省了很大的时间; 向您致敬
2
红薯
红薯
下面是我用来列举所有线程的jsp页面:
<html>
<head>
<title>Threads in ldcstudy.com</title>
<style>
body {font-size:8pt;}
ol {line-height:18px;}
</style>
</head>
<body>
<strong>java.io.tmpdir:</strong>
<ul>
<li><%=System.getProperty("java.io.tmpdir")%></li>
</ul>
<br/>
<strong>Memory:</strong>
<ol>
<li>freeMemory=<%=Runtime.getRuntime().freeMemory()/(1024*1024)%>M</li>
    <li>totalMemory=<%=Runtime.getRuntime().totalMemory()/(1024*1024)%>M</li>
    <li>maxMemory=<%=Runtime.getRuntime().maxMemory()/(1024*1024)%>M</li>
</ol>
<br/>
<strong>Thread:</strong>
<ol>
<%for(Thread t : list_threads()){%>
<li><%=t.getName()%>(<b><%=t.getState()%></b>) : <%=t.getClass().getName()%></li>
<%}%>
</ol>
<%!
public static java.util.List<Thread> list_threads(){
	int tc = Thread.activeCount();
	Thread[] ts = new Thread[tc];
	Thread.enumerate(ts);
	return java.util.Arrays.asList(ts);
}
%>
</body>
</html>
Occur_K
Occur_K
请教,怎么打印出线程对应的URL?
汉唐
汉唐
谢谢分享,学习了
FoxHu
FoxHu
试了一下,这个好用!
0
红薯
红薯
我还碰到的导致CPU 100%的原因,是程序某个地方存在死循环,这个死循环在某种条件下存在,因此通过上面的方法可能找出来
丑丑泡泡猴
丑丑泡泡猴
@红薯 堆内存那有时会很高是啥原因导致的?
0
Z
ZYud

 

既然可以用visualVM,使用thread dump也可以实现查看当前线程

0
恺哥
恺哥

感谢大家的回复

我现在折腾一下,待解决后,给出结论,谢谢大家

0
foxbrother
foxbrother
红薯老大 搞java很多年啊,功力深厚。
0
steel
steel
学习了,借鉴下
0
恺哥
恺哥

问题解决

解决过程如下:

通过visualVM监视活动进程,发现有很多ip:8881 reciver线程在活动,有上百条之多

此时关闭tomcat,然后重启

发现ip:8881 reciver线程陆续增长

通过查询ip获知,该ip是联通短信网关的服务地址

突然恍然大悟,是不是开发人员在调用完短信网关后未关闭连接

此时让测试人员向我的手机发送一个短信发现,发送一条,活动线程增加一条

然后找到其代码发现,确实是连接没有关闭

果断加上try finally之后,该线程消失,cpu利用率恢复到正常水平

感谢大家

恺哥
恺哥
回复 @_笔记本_ : 之所以在其他服务器上没有问题,是因为在其他服务器上并没有测试群发短信的用例,只发1,2条短信的话是发现不了资源未关闭导致的线程只增不减的问题
_笔记本_
_笔记本_
既然是这个原因,为什么在其他服务器上没问题?
0
我土鳖
这就算是资源泄漏吧。
0
ExtremeTalk
ExtremeTalk
700多个线程,真不少
ExtremeTalk
ExtremeTalk
你没用线程池吗?或者,你的线程需要一直存活着?
恺哥
恺哥
发一条短信,新建一个线程,你算算。
返回顶部
顶部