報錯!-> CPU100%-但是找不到使用cpu的進程


       

                                                                         cpu到達100%   但是找不到使用cpu的進程

 

一般分析cpu使用率:通過使用 topvmstatpidstat 等工具,排查高 CPU 使用率的進程,然后再使用 perf top 工具,定位應用內部函數的問題。

但是!不是所有cpu過高都是這樣分析的,這只是一般情況下可以這樣分析。什么是一般情況?簡單說,通常可以根據工具,就可以找到cpu占有過高的進程!

   通過top命令我們知道,系統cpu使用率基本包括

  • 進程用戶狀態的運行
  • 內核狀態的運行
  • 中斷處理的線程
  • 等待I/O的線程
  • 內核線程

以前看到cpu過高時,簡單的以為是某一個進程占用過大導致的,其實不一定,系統CPU過高,不一定是進程引起的,還有可能是IO過高或者阻塞引起的,也有可能是中斷進程引起的,多方面原因分析:如圖:

                                                                                                                                                                                                                                                                                                

如下一個案例

使用TOP命令

$ top

top - 04:58:24 up 14 days, 15:47,  1 user,  load average: 3.39, 3.82, 2.74

Tasks: 149 total,   6 running,  93 sleeping,   0 stopped,   0 zombie

%Cpu(s): 77.7 us, 19.3 sy,  0.0 ni,  2.0 id,  0.0 wa,  0.0 hi,  1.0 si,  0.0 st

KiB Mem :  8169348 total,  2543916 free,   457976 used,  5167456 buff/cache

KiB Swap:        0 total,        0 free,        0 used.  7363908 avail Mem

 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND

 6947 systemd+  20   0   33104   3764   2340 S   4.0  0.0   0:32.69 nginx

 6882 root      20   0   12108   8360   3884 S   2.0  0.1   0:31.40 docker-containe

15465 daemon    20   0  336696  15256   7576 S   2.0  0.2   0:00.62 php-fpm

15466 daemon    20   0  336696  15196   7516 S   2.0  0.2   0:00.62 php-fpm

15489 daemon    20   0  336696  16200   8520 S   2.0  0.2   0:00.62 php-fpm

 6948 systemd+  20   0   33104   3764   2340 S   1.0  0.0   0:00.95 nginx

15006 root      20   0 1168608  65632  37536 S   1.0  0.8   9:51.09 dockerd

15476 daemon    20   0  336696  16200   8520 S   1.0  0.2   0:00.61 php-fpm

15477 daemon    20   0  336696  16200   8520 S   1.0  0.2   0:00.61 php-fpm

24340 daemon    20   0    8184   1616    536 R   1.0  0.0   0:00.01 stress

24342 daemon    20   0    8196   1580    492 R   1.0  0.0   0:00.01 stress

24344 daemon    20   0    8188   1056    492 R   1.0  0.0   0:00.01 stress

24347 daemon    20   0    8184   1356    540 R   1.0  0.0   0:00.01 stress

...

這次從頭開始看 top 的每行輸出,Tasks 這一行看起來有點奇怪,就緒隊列中居然有 6 Running 狀態的進程(6 running),是不是有點多呢?

 

然后用 pidstat 命令看一下它的 CPU 使用情況:

 

 

$ pidstat -p 24344

 

 

 

16:14:55      UID       PID    %usr %system  %guest   %wait    %CPU   CPU  Command

 

奇怪,居然沒有任何輸出。難道是 pidstat 命令出問題了嗎?我們在終端里運行下面的命令,看看 24344 進程的狀態:

 

# 從所有進程中查找 PID 24344 的進程

 

$ ps aux | grep 24344

 

root      9628  0.0  0.0  14856  1096 pts/0    S+   16:15   0:00 grep --color=auto 24344

 

還是沒有輸出。現在終於發現問題,原來這個進程已經不存在了,所以 pidstat 就沒有任何輸出。既然進程都沒了,那性能問題應該也跟着沒了吧

然后再一次top一下

 

 

$ top

 

...

 

%Cpu(s): 80.9 us, 14.9 sy,  0.0 ni,  2.8 id,  0.0 wa,  0.0 hi,  1.3 si,  0.0 st

 

...

 

 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND

 

 6882 root      20   0   12108   8360   3884 S   2.7  0.1   0:45.63 docker-containe

 

 6947 systemd+  20   0   33104   3764   2340 R   2.7  0.0   0:47.79 nginx

 

 3865 daemon    20   0  336696  15056   7376 S   2.0  0.2   0:00.15 php-fpm

 

  6779 daemon    20   0    8184   1112    556 R   0.3  0.0   0:00.01 stress

 

...

 

好像又錯了。結果還跟原來一樣,用戶 CPU 使用率還是高達 80.9%,系統 CPU 接近 15%,而空閑 CPU 只有 2.8%Running 狀態的進程有 Nginxstress 等。

 

 

 

可是,剛剛我們看到 stress 進程不存在了,怎么現在還在運行呢?再細看一下 top 的輸出,原來,這次 stress 進程的 PID 跟前面不一樣了,原來的 PID 24344 不見了,現在的是 6779

那么問題來了,stress這個進程再不斷的變換PID,是什么原因呢?

一個進程不斷的變換Pid號,無非兩種原因  

   第一個原因:進程在不停地崩潰重啟,比如因為段錯誤、配置錯誤等等,這時,進程在退出后可能又被監控系統自動重啟了

 

 

   第二個原因:這些進程都是短時進程,也就是在其他應用內部通過 exec 調用的外面命令。這些命令一般都只運行很短的時間就會結束,很難用 top 這種間隔時間比較長的工具發現

 

通過這兩種原因,看來,top命令也不是萬能的,也會有些速度快的進程逃過他的檢查(天下武功,唯快不破)

回到問題:stress這個進程不斷的變換PID,又占用用cpu資源,導致cpu過高,這個時候,找到它的父進程,來進行下一步分析

使用pstree命令來看進程關系,找到它的父進程!

看看是不是父進程里有什么調用問題,看看父進程的源碼

一大部分可能是————————————————

由於權限錯誤,大量的 stress 進程在啟動時初始化失敗,進而導致用戶 CPU 使用率的升高。或者是二進制文件里有對stress有大量的調用循環。

 

問題總結:

 

碰到常規問題無法解釋的 CPU 使用率情況時,首先要想到有可能是短時應用導致的問題,比如有可能是下面這兩種情況

  • 應用里直接調用了其他二進制程序,這些程序通常會運行時間很短,速度非常快,通過top等其他工具不一定能查詢的到
  • 應用本身就在不停的崩潰重啟,而啟動過程的資源初始化,很可能會占用大量的CPU,而且這類進程,PID會不斷變更,通常只能通過pstree或者execsnoop找到它的父進程,從父進程所在的應用里查找,找到問題所在,排查問題。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM