06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
生活随笔
收集整理的這篇文章主要介紹了
06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上一節我講了 CPU 使用率是什么,并通過一個案例教你使用 top、vmstat、pidstat 等工具,排查高 CPU 使用率的進程,然后再使用 perf top 工具,定位應用內部函數的問題。不過就有人留言了,說似乎感覺高 CPU 使用率的問題,還是挺容易排查的。那是不是所有 CPU 使用率高的問題,都可以這么分析呢?我想,你的答案應該是否定的?;仡櫱懊娴膬热?#xff0c;我們知道,系統的 CPU 使用率,不僅包括進程用戶態和內核態的運行,還包括中斷處理、等待 I/O 以及內核線程等。所以,當你發現系統的 CPU 使用率很高的時候,不一定能找到相對應的高 CPU 使用率的進程。今天,我就用一個 Nginx + PHP 的 Web 服務的案例,帶你來分析這種情況。
案例分析
你的準備
今天依舊探究系統 CPU 使用率高的情況,所以這次實驗的準備工作,與上節課的準備工作基本相同,差別在于案例所用的 Docker 鏡像不同。本次案例還是基于 Ubuntu 18.04,同樣適用于其他的 Linux 系統。我使用的案例環境如下所示:- 機器配置:2 CPU,8GB 內存
- 預先安裝 docker、sysstat、perf、ab 等工具,如 apt install docker.io sysstat linux-tools-common apache2-utils
操作和分析
首先,我們在第一個終端,執行下面的命令運行 Nginx 和 PHP 應用:$ docker run --name nginx -p 10000:80 -itd feisky/nginx:sp $ docker run --name phpfpm -itd --network container:nginx feisky/php-fpm:sp然后,在第二個終端,使用 curl 訪問 http://[VM1 的 IP]:10000,確認 Nginx 已正常啟動。你應該可以看到 It works! 的響應。# 192.168.0.10 是第一臺虛擬機的 IP 地址 $ curl http://192.168.0.10:10000/ It works!接著,我們來測試一下這個 Nginx 服務的性能。在第二個終端運行下面的 ab 命令。要注意,與上次操作不同的是,這次我們需要并發 100 個請求測試 Nginx 性能,總共測試 1000 個請求。# 并發 100 個請求測試 Nginx 性能,總共測試 1000 個請求 $ ab -c 100 -n 1000 http://192.168.0.10:10000/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, ... Requests per second: 87.86 [#/sec] (mean) Time per request: 1138.229 [ms] (mean) ...從 ab 的輸出結果我們可以看到,Nginx 能承受的每秒平均請求數,只有 87 多一點,是不是感覺它的性能有點差呀。那么,到底是哪里出了問題呢?我們再用 top 和 pidstat 來觀察一下。這次,我們在第二個終端,將測試的并發請求數改成 5,同時把請求時長設置為 10 分鐘(-t 600)。這樣,當你在第一個終端使用性能分析工具時, Nginx 的壓力還是繼續的。繼續在第二個終端運行 ab 命令:$ ab -c 5 -t 600 http://192.168.0.10:10000/然后,我們在第一個終端運行 top 命令,觀察系統的 CPU 使用情況:$ top ... %Cpu(s): 80.8 us, 15.1 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+ COMMAND6882 root 20 0 8456 5052 3884 S 2.7 0.1 0:04.78 docker-containe6947 systemd+ 20 0 33104 3716 2340 S 2.7 0.0 0:04.92 nginx7494 daemon 20 0 336696 15012 7332 S 2.0 0.2 0:03.55 php-fpm7495 daemon 20 0 336696 15160 7480 S 2.0 0.2 0:03.55 php-fpm 10547 daemon 20 0 336696 16200 8520 S 2.0 0.2 0:03.13 php-fpm 10155 daemon 20 0 336696 16200 8520 S 1.7 0.2 0:03.12 php-fpm 10552 daemon 20 0 336696 16200 8520 S 1.7 0.2 0:03.12 php-fpm 15006 root 20 0 1168608 66264 37536 S 1.0 0.8 9:39.51 dockerd4323 root 20 0 0 0 0 I 0.3 0.0 0:00.87 kworker/u4:1 ...觀察 top 輸出的進程列表可以發現,CPU 使用率最高的進程也只不過才 2.7%,看起來并不高。然而,再看系統 CPU 使用率( %Cpu )這一行,你會發現,系統的整體 CPU 使用率是比較高的:用戶 CPU 使用率(us)已經到了 80%,系統 CPU 為 15.1%,而空閑 CPU (id)則只有 2.8%。為什么用戶 CPU 使用率這么高呢?我們再重新分析一下進程列表,看看有沒有可疑進程:- docker-containerd 進程是用來運行容器的,2.7% 的 CPU 使用率看起來正常;
- Nginx 和 php-fpm 是運行 Web 服務的,它們會占用一些 CPU 也不意外,并且 2% 的 CPU 使用率也不算高;
- 再往下看,后面的進程呢,只有 0.3% 的 CPU 使用率,看起來不太像會導致用戶 CPU 使用率達到 80%。
- 第一個原因,進程在不停地崩潰重啟,比如因為段錯誤、配置錯誤等等,這時,進程在退出后可能又被監控系統自動重啟了。
- 第二個原因,這些進程都是短時進程,也就是在其他應用內部通過 exec 調用的外面命令。這些命令一般都只運行很短的時間就會結束,你很難用 top 這種間隔時間比較長的工具發現(上面的案例,我們碰巧發現了)。
execsnoop
在這個案例中,我們使用了 top、pidstat、pstree 等工具分析了系統 CPU 使用率高的問題,并發現 CPU 升高是短時進程 stress 導致的,但是整個分析過程還是比較復雜的。對于這類問題,有沒有更好的方法監控呢?execsnoop 就是一個專為短時進程設計的工具。它通過 ftrace 實時監控進程的 exec() 行為,并輸出短時進程的基本信息,包括進程 PID、父進程 PID、命令行參數以及執行的結果。比如,用 execsnoop 監控上述案例,就可以直接得到 stress 進程的父進程 PID 以及它的命令行參數,并可以發現大量的 stress 進程在不停啟動:# 按 Ctrl+C 結束 $ execsnoop PCOMM PID PPID RET ARGS sh 30394 30393 0 stress 30396 30394 0 /usr/local/bin/stress -t 1 -d 1 sh 30398 30393 0 stress 30399 30398 0 /usr/local/bin/stress -t 1 -d 1 sh 30402 30400 0 stress 30403 30402 0 /usr/local/bin/stress -t 1 -d 1 sh 30405 30393 0 stress 30407 30405 0 /usr/local/bin/stress -t 1 -d 1 ...execsnoop 所用的 ftrace 是一種常用的動態追蹤技術,一般用于分析 Linux 內核的運行時行為,后面課程我也會詳細介紹并帶你使用。小結
碰到常規問題無法解釋的 CPU 使用率情況時,首先要想到有可能是短時應用導致的問題,比如有可能是下面這兩種情況。第一,應用里直接調用了其他二進制程序,這些程序通常運行時間比較短,通過 top 等工具也不容易發現。第二,應用本身在不停地崩潰重啟,而啟動過程的資源初始化,很可能會占用相當多的 CPU。對于這類進程,我們可以用 pstree 或者 execsnoop 找到它們的父進程,再從父進程所在的應用入手,排查問題的根源。perf record -ag -- sleep 2;perf report一部到位總結
以上是生活随笔為你收集整理的06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 04 | 基础篇:经常说的 CPU 上下
- 下一篇: 07 | 案例篇:系统中出现大量不可中断