問題描述:
最近在測試環境的服務器上,無意中發現cpu持續飆高。最高的時候達到了200%經過反復重啟無效之后,決定挖掘深層次的原因
通過top命令打印出消耗cpu的pid,如圖
通過ps -mp 24597 -o THREAD,tid,time,找出進程中cpu占用率最高的tid
通過 jstack -F tid >> tid.log打印出該進程下的線程信息
在文件中可以看到一行怪異的信息
從線程信息中,可以看到,似乎是這個線程調用某一個dubbo服務的時候,線程阻塞了,持續消耗cpu
排查之后沒有結論。。。
-------------------------------------------------------------------------分割線----------------------------------------------------------------------------------------
換一種排查方式。。。
用 vmstat 1 10 命令看一下可能存在的問題
下圖中可以發現in和cs值有些異常
in:表示每秒cpu中斷的次數
cs:表示每秒產生的 上下文切換數。我們調用函數,就要進行上下文切換;線程間的切換,也要進程上下文切換。
這個值越小越好,太大了,要考慮調低線程或者進程的數目。
我們做大並發測試時,選擇web服務器的進程可以從進程或者線程的峰值一直下調,壓測,直到cs到一個比較小的值,這個進程和線程數就是比較合適的值。
另外,每次調用系統函數,我們的代碼就會進入內核空間,導致上下文切換,這個很耗資源,要盡量避免頻繁調用。
上下文切換次數過多表示你的CPU大部分浪費在上下文切換,導致CPU不能充分利用和正常工作。
in和cs值越大,表示內核消耗的cpu越多
接下來我們看一下關鍵進程的上下文切換數
先找出消耗cpu最大的進程
top -Hp 24597
pid =24619
查看一下該進程的上下文切換數
pidstat -p 24619 -w 1 10
- PID:進程id
- Cswch/s:每秒主動任務上下文切換數量
- Nvcswch/s:每秒被動任務上下文切換數量
- Command:命令名
可以看出該進程每秒都在被動的切換上下文,而且數量很大
用pstack查看一下線程日志
似乎是sleep的問題,未完待續。。。。
-------------------------------------------------------------------------分割線----------------------------------------------------------------------------------------
跨度有點久了,現在終於找到了問題根源
通過線程分析工具,打印出了占用cpu最高的方法調用
bash show-busy-java-threads
原來是target目錄下dubbo文件的權限有問題,因為該文件不是當期用戶權限,所以讀取的時候產生了死循環,導致cpu飆高
把這個文件的權限改成當前用戶,然后重啟一下tomcat。cpu就降下來了