06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
生活随笔
收集整理的這篇文章主要介紹了
06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
上一節(jié)我講了 CPU 使用率是什么,并通過一個案例教你使用 top、vmstat、pidstat 等工具,排查高 CPU 使用率的進(jìn)程,然后再使用 perf top 工具,定位應(yīng)用內(nèi)部函數(shù)的問題。不過就有人留言了,說似乎感覺高 CPU 使用率的問題,還是挺容易排查的。那是不是所有 CPU 使用率高的問題,都可以這么分析呢?我想,你的答案應(yīng)該是否定的?;仡櫱懊娴膬?nèi)容,我們知道,系統(tǒng)的 CPU 使用率,不僅包括進(jìn)程用戶態(tài)和內(nèi)核態(tài)的運(yùn)行,還包括中斷處理、等待 I/O 以及內(nèi)核線程等。所以,當(dāng)你發(fā)現(xiàn)系統(tǒng)的 CPU 使用率很高的時候,不一定能找到相對應(yīng)的高 CPU 使用率的進(jìn)程。今天,我就用一個 Nginx + PHP 的 Web 服務(wù)的案例,帶你來分析這種情況。
案例分析
你的準(zhǔn)備
今天依舊探究系統(tǒng) CPU 使用率高的情況,所以這次實(shí)驗(yàn)的準(zhǔn)備工作,與上節(jié)課的準(zhǔn)備工作基本相同,差別在于案例所用的 Docker 鏡像不同。本次案例還是基于 Ubuntu 18.04,同樣適用于其他的 Linux 系統(tǒng)。我使用的案例環(huán)境如下所示:- 機(jī)器配置:2 CPU,8GB 內(nèi)存
- 預(yù)先安裝 docker、sysstat、perf、ab 等工具,如 apt install docker.io sysstat linux-tools-common apache2-utils
操作和分析
首先,我們在第一個終端,執(zhí)行下面的命令運(yùn)行 Nginx 和 PHP 應(yīng)用:$ 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,確認(rèn) Nginx 已正常啟動。你應(yīng)該可以看到 It works! 的響應(yīng)。# 192.168.0.10 是第一臺虛擬機(jī)的 IP 地址 $ curl http://192.168.0.10:10000/ It works!接著,我們來測試一下這個 Nginx 服務(wù)的性能。在第二個終端運(yùn)行下面的 ab 命令。要注意,與上次操作不同的是,這次我們需要并發(fā) 100 個請求測試 Nginx 性能,總共測試 1000 個請求。# 并發(fā) 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 的輸出結(jié)果我們可以看到,Nginx 能承受的每秒平均請求數(shù),只有 87 多一點(diǎn),是不是感覺它的性能有點(diǎn)差呀。那么,到底是哪里出了問題呢?我們再用 top 和 pidstat 來觀察一下。這次,我們在第二個終端,將測試的并發(fā)請求數(shù)改成 5,同時把請求時長設(shè)置為 10 分鐘(-t 600)。這樣,當(dāng)你在第一個終端使用性能分析工具時, Nginx 的壓力還是繼續(xù)的。繼續(xù)在第二個終端運(yùn)行 ab 命令:$ ab -c 5 -t 600 http://192.168.0.10:10000/然后,我們在第一個終端運(yùn)行 top 命令,觀察系統(tǒng)的 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 輸出的進(jìn)程列表可以發(fā)現(xiàn),CPU 使用率最高的進(jìn)程也只不過才 2.7%,看起來并不高。然而,再看系統(tǒng) CPU 使用率( %Cpu )這一行,你會發(fā)現(xiàn),系統(tǒng)的整體 CPU 使用率是比較高的:用戶 CPU 使用率(us)已經(jīng)到了 80%,系統(tǒng) CPU 為 15.1%,而空閑 CPU (id)則只有 2.8%。為什么用戶 CPU 使用率這么高呢?我們再重新分析一下進(jìn)程列表,看看有沒有可疑進(jìn)程:- docker-containerd 進(jìn)程是用來運(yùn)行容器的,2.7% 的 CPU 使用率看起來正常;
- Nginx 和 php-fpm 是運(yùn)行 Web 服務(wù)的,它們會占用一些 CPU 也不意外,并且 2% 的 CPU 使用率也不算高;
- 再往下看,后面的進(jìn)程呢,只有 0.3% 的 CPU 使用率,看起來不太像會導(dǎo)致用戶 CPU 使用率達(dá)到 80%。
- 第一個原因,進(jìn)程在不停地崩潰重啟,比如因?yàn)槎五e誤、配置錯誤等等,這時,進(jìn)程在退出后可能又被監(jiān)控系統(tǒng)自動重啟了。
- 第二個原因,這些進(jìn)程都是短時進(jìn)程,也就是在其他應(yīng)用內(nèi)部通過 exec 調(diào)用的外面命令。這些命令一般都只運(yùn)行很短的時間就會結(jié)束,你很難用 top 這種間隔時間比較長的工具發(fā)現(xiàn)(上面的案例,我們碰巧發(fā)現(xiàn)了)。
execsnoop
在這個案例中,我們使用了 top、pidstat、pstree 等工具分析了系統(tǒng) CPU 使用率高的問題,并發(fā)現(xiàn) CPU 升高是短時進(jìn)程 stress 導(dǎo)致的,但是整個分析過程還是比較復(fù)雜的。對于這類問題,有沒有更好的方法監(jiān)控呢?execsnoop 就是一個專為短時進(jìn)程設(shè)計的工具。它通過 ftrace 實(shí)時監(jiān)控進(jìn)程的 exec() 行為,并輸出短時進(jìn)程的基本信息,包括進(jìn)程 PID、父進(jìn)程 PID、命令行參數(shù)以及執(zhí)行的結(jié)果。比如,用 execsnoop 監(jiān)控上述案例,就可以直接得到 stress 進(jìn)程的父進(jìn)程 PID 以及它的命令行參數(shù),并可以發(fā)現(xiàn)大量的 stress 進(jìn)程在不停啟動:# 按 Ctrl+C 結(jié)束 $ 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 是一種常用的動態(tài)追蹤技術(shù),一般用于分析 Linux 內(nèi)核的運(yùn)行時行為,后面課程我也會詳細(xì)介紹并帶你使用。小結(jié)
碰到常規(guī)問題無法解釋的 CPU 使用率情況時,首先要想到有可能是短時應(yīng)用導(dǎo)致的問題,比如有可能是下面這兩種情況。第一,應(yīng)用里直接調(diào)用了其他二進(jìn)制程序,這些程序通常運(yùn)行時間比較短,通過 top 等工具也不容易發(fā)現(xiàn)。第二,應(yīng)用本身在不停地崩潰重啟,而啟動過程的資源初始化,很可能會占用相當(dāng)多的 CPU。對于這類進(jìn)程,我們可以用 pstree 或者 execsnoop 找到它們的父進(jìn)程,再從父進(jìn)程所在的應(yīng)用入手,排查問題的根源。perf record -ag -- sleep 2;perf report一部到位總結(jié)
以上是生活随笔為你收集整理的06 | 案例篇:系统的 CPU 使用率很高,但为啥却找不到高 CPU 的应用?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 04 | 基础篇:经常说的 CPU 上下
- 下一篇: 07 | 案例篇:系统中出现大量不可中断