cpu负载太高案例,解决方法记录

先讲下问题来源,前一段时间线上服务器负载高的吓人,做为一台只部署了tomcat的应用服务器,平时load average 也就在零点几的水平,忽然达到十几真是让人惊了个呆(⊙ˍ⊙),生怕服务器分分钟宕掉啊。html

赶忙找问题发生缘由吧,我之前没有遇到过这类问题,没啥经验可谈,首先服务器上top下,发现最耗cpu的就是咱们的应用服务器,如图:java

负载高

我立刻想到的是咱们有异步处理的多线程程序,是否是哪一个程序死锁了或者一直跑着,不释放。因而查看了最近修改的代码,也没有发现那里可能会发生死循环,那干脆打印下堆栈看看到底都有什么线程在跑着吧。到jdk的bin路径下 用jstack pid >xxx.stack命令打印堆栈内容。linux

堆栈

快1MB的内容,真的无法去找,都是一些TIMED_WAITINGWAITING这些能够先不用去看,优先级高的应该是那些RUNNABLE的,由于都已经等待了,就消耗不到cpu了啊。看了半天也没看出啥名堂,最后在其余博客上取取经,发现了实用的技巧。tomcat

具体思路:服务器

首先要找到哪几个线程在占用cpu,以后再经过线程的id值在堆栈文件中查找具体的线程,看看出来什么问题。多线程

OK,实战开始,第一个命令异步

ps -mp pid -o THREAD,tid,time

其中pid 换成要查看的进程的id值,这个命令的做用就是打印出进程下有哪几个线程在跑,而且分别占用cpu多长时间。.net

ps不熟悉话,能够在linux下查看man ps文档,看看具体那几个命令的做用线程

-p的后面跟着要显示的进程的id号, -m的意思是显示这个进程下的全部线程 -o的意思是格式化要输出的内容code

经过上边这个命令,显示出一堆线程,经过筛选以后发现了几个占用cpu很长的线程

%CPU TID TIME
17.3 16172 12:18:58
79.9 16275 2-08:49:22
19.8 418 12:16:02
32.6 13071 12:17:14

这下可算找到罪魁祸首了,看第二个线程cpu占用的吓人,而且占用时间也是高的离谱,我记住它了( *⊙~⊙)。

第二个命令,将找到的线程id号转成十六进制

printf "%x\n" tid

这个很简单,就不解释了,获得结果是3f93

以后就是在最初打印的堆栈信息中查找这个线程,Bingo!

bug_problem

请原谅,把关键信息注释上了,哈哈。找到这个线程,能够看到具体出问题的代码行了,对就是我注释那几个代码行,以后就在源码中查找下,发现真的有一个死循环在那里(⊙﹏⊙)b,好了既然找到了那就fix掉就能够了。

在一次上线以后服务器的状况:

fix_bug

又健健康康的啦~~~。

结尾再费点唾沫,查找好cpu的线程时一共有四个,其实那三个我也找了,发现是咱们本身建立的线程池,因此不是问题啦。

参考文章: 线上应用故障排查之一:高CPU占用

相关文章
相关标签/搜索