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佔用

相關文章
相關標籤/搜索