這篇文章是極客時(shí)間專欄《Linux性能優(yōu)化實(shí)戰(zhàn)》 05 |基本篇:如果某個應(yīng)用程序的CPU利用率達(dá)到100%,該怎么辦?

CPU 使用率

***為了保持CPU時(shí)間,Linux通過預(yù)定義的比特率(在內(nèi)核中以HZ表示)觸發(fā)時(shí)間中斷,并使用全局變量Jiffies記錄啟動后的位數(shù)。

每發(fā)生一次時(shí)間中斷,Jiffies 的值就加 1。
節(jié)拍率 HZ 是內(nèi)核的可配選項(xiàng),可以設(shè)置為 100、250、1000 等。不同的系統(tǒng)可能設(shè)置不同數(shù)值,你可以通過查詢 /boot/config 內(nèi)核選項(xiàng)來查看它的配置值。比如在我的系統(tǒng)中,節(jié)拍率設(shè)置成了 250,也就是每秒鐘觸發(fā) 250 次時(shí)間中斷。

$ grep 'CONFIG_HZ=' /boot/config-$(uname -r) CONFIG_HZ=250

同時(shí),正因?yàn)楣?jié)拍率 HZ 是內(nèi)核選項(xiàng),所以用戶空間程序并不能直接訪問。為了方便用戶空間程序,內(nèi)核還提供了一個用戶空間節(jié)拍率 USERHZ,它總是固定為 100,也就是 1/100 秒。這樣,用戶空間程序并不需要關(guān)心內(nèi)核中 HZ 被設(shè)置成了多少,因?yàn)樗吹降目偸枪潭ㄖ?USERHZ。
Linux 通過 /proc 虛擬文件系統(tǒng),向用戶空間提供了系統(tǒng)內(nèi)部狀態(tài)的信息,而 /proc/stat 提供的就是系統(tǒng)的 CPU 和任務(wù)統(tǒng)計(jì)信息。比方說,如果你只關(guān)注 CPU 的話,可以執(zhí)行下面的命令:

# 只保留各個CPU的數(shù)據(jù) $ cat /proc/stat | grep ^cpu cpu 280580 7407 286084 172900810 83602 0 583 0 0 0 cpu0 144745 4181 176701 86423902 52076 0 301 0 0 0 cpu1 135834 3226 109383 86476907 31525 0 282 0 0 0

這里的輸出結(jié)果是一個表格。其中,第一列表示的是 CPU 編號,如 cpu0、cpu1 ,而第一行沒有編號的 cpu ,表示的是所有 CPU 的累加。其他列則表示不同場景下 CPU 的累加節(jié)拍數(shù),它的單位是 USER_HZ,也就是 10 ms(1/100 秒),所以這其實(shí)就是不同場景下的 CPU 時(shí)間。
當(dāng)然,這里每一列的順序并不需要你背下來。你只要記住,有需要的時(shí)候,查詢 man proc 就可以。不過,你要清楚 man proc 文檔里每一列的涵義,它們都是 CPU 使用率相關(guān)的重要指標(biāo),你還會在很多其他的性能工具中看到它們。下面,我來依次解讀一下。

  • user(通??s寫為 us),代表用戶態(tài) CPU 時(shí)間。注意,它不包括下面的 nice 時(shí)間,但包括了 guest 時(shí)間。
  • nice(通常縮寫為 ni),代表低優(yōu)先級用戶態(tài) CPU 時(shí)間,也就是進(jìn)程的 nice 值被調(diào)整為 1-19 之間時(shí)的 CPU 時(shí)間。這里注意,nice 可取值范圍是 -20 到 19,數(shù)值越大,優(yōu)先級反而越低。
  • system(通常縮寫為 sys),代表內(nèi)核態(tài) CPU 時(shí)間。
  • idle(通??s寫為 id),代表空閑時(shí)間。注意,它不包括等待 I/O 的時(shí)間(iowait)。
  • iowait(通??s寫為 wa),代表等待 I/O 的 CPU 時(shí)間。
  • irq(通??s寫為 hi),代表處理硬中斷的 CPU 時(shí)間。
  • softirq(通??s寫為 si),代表處理軟中斷的 CPU 時(shí)間。
  • steal(通??s寫為 st),代表當(dāng)系統(tǒng)運(yùn)行在虛擬機(jī)中的時(shí)候,被其他虛擬機(jī)占用的 CPU 時(shí)間。
  • guest(通常縮寫為 guest),代表通過虛擬化運(yùn)行其他操作系統(tǒng)的時(shí)間,也就是運(yùn)行虛擬機(jī)的 CPU 時(shí)間。
  • guest_nice(通??s寫為 gnice),代表以低優(yōu)先級運(yùn)行虛擬機(jī)的時(shí)間。
    而我們通常所說的 CPU 使用率,就是除了空閑時(shí)間外的其他時(shí)間占總 CPU 時(shí)間的百分比,用公式來表示就是:

怎么查看 CPU 使用率

top 和 ps 是最常用的性能分析工具:top 顯示了系統(tǒng)總體的 CPU 和內(nèi)存使用情況,以及各個進(jìn)程的資源使用情況。ps 則只顯示了每個進(jìn)程的資源使用情況。

# 默認(rèn)每3秒刷新一次 $ top top - 11:58:59 up 9 days, 22:47, 1 user, load average: 0.03, 0.02, 0.00 Tasks: 123 total, 1 running, 72 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.3 us, 0.3 sy, 0.0 ni, 99.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 8169348 total, 5606884 free, 334640 used, 2227824 buff/cache KiB Swap: 0 total, 0 free, 0 used. 7497908 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1 root 20 0 78088 9288 6696 S 0.0 0.1 0:16.83 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.05 kthreadd 4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H ...

這個輸出結(jié)果中,top 默認(rèn)顯示的是所有 CPU 的平均值,這個時(shí)候你只需要按下數(shù)字 1 ,就可以切換到每個 CPU 的使用率了。
繼續(xù)往下看,空白行之后是進(jìn)程的實(shí)時(shí)信息,每個進(jìn)程都有一個 %CPU 列,表示進(jìn)程的 CPU 使用率。它是用戶態(tài)和內(nèi)核態(tài) CPU 使用率的總和,包括進(jìn)程用戶空間使用的 CPU、通過系統(tǒng)調(diào)用執(zhí)行的內(nèi)核空間 CPU 、以及在就緒隊(duì)列等待運(yùn)行的 CPU。在虛擬化環(huán)境中,它還包括了運(yùn)行虛擬機(jī)占用的 CPU。
用 pidstat 吧,它正是一個專門分析每個進(jìn)程 CPU 使用情況的工具。下面的 pidstat 命令,就間隔 1 秒展示了進(jìn)程的 5 組 CPU 使用率,包括:

  • 用戶態(tài) CPU 使用率 (%usr);
  • 內(nèi)核態(tài) CPU 使用率(%system);
  • 運(yùn)行虛擬機(jī) CPU 使用率(%guest);
  • 等待 CPU 使用率(%wait);
  • 以及總的 CPU 使用率(%CPU)。
    最后的 Average 部分,還計(jì)算了 5 組數(shù)據(jù)的平均值。
# 每隔1秒輸出一組數(shù)據(jù),共輸出5組 $ pidstat 1 5 15:56:02 UID PID %usr %system %guest %wait %CPU CPU Command 15:56:03 0 15006 0.00 0.99 0.00 0.00 0.99 1 dockerd ... Average: UID PID %usr %system %guest %wait %CPU CPU Command Average: 0 15006 0.00 0.99 0.00 0.00 0.99 - dockerd

CPU 使用率過高怎么辦?

使用 perf 分析 CPU 性能問題,我來說兩種最常見、也是我最喜歡的用法。
第一種常見用法是 perf top,類似于 top,它能夠?qū)崟r(shí)顯示占用 CPU 時(shí)鐘最多的函數(shù)或者指令,因此可以用來查找熱點(diǎn)函數(shù),使用界面如下所示:

$ perf top Samples: 833 of event 'cpu-clock', Event count (approx.): 97742399 Overhead Shared Object Symbol 7.28% perf [.] 0x00000000001f78a4 4.72% [kernel] [k] vsnprintf 4.32% [kernel] [k] module_get_kallsym 3.65% [kernel] [k] _raw_spin_unlock_irqrestore ...

輸出結(jié)果中,第一行包含三個數(shù)據(jù),分別是采樣數(shù)(Samples)、事件類型(event)和事件總數(shù)量(Event count)。比如這個例子中,perf 總共采集了 833 個 CPU 時(shí)鐘事件,而總事件數(shù)則為 97742399。
再往下看是一個表格式樣的數(shù)據(jù),每一行包含四列,分別是:

  • 第一列 Overhead ,是該符號的性能事件在所有采樣中的比例,用百分比來表示。
  • 第二列 Shared ,是該函數(shù)或指令所在的動態(tài)共享對象(Dynamic Shared Object),如內(nèi)核、進(jìn)程名、動態(tài)鏈接庫名、內(nèi)核模塊名等。
  • 第三列 Object ,是動態(tài)共享對象的類型。比如 [.] 表示用戶空間的可執(zhí)行程序、或者動態(tài)鏈接庫,而 [k] 則表示內(nèi)核空間。
  • 最后一列 Symbol 是符號名,也就是函數(shù)名。當(dāng)函數(shù)名未知時(shí),用十六進(jìn)制的地址來表示。
    還是以上面的輸出為例,我們可以看到,占用 CPU 時(shí)鐘最多的是 perf 工具自身,不過它的比例也只有 7.28%,說明系統(tǒng)并沒有 CPU 性能問題。 perf top 的使用你應(yīng)該很清楚了吧。
    接著再來看第二種常見用法,也就是 perf record 和 perf report。 perf top 雖然實(shí)時(shí)展示了系統(tǒng)的性能信息,但它的缺點(diǎn)是并不保存數(shù)據(jù),也就無法用于離線或者后續(xù)的分析。而 perf record 則提供了保存數(shù)據(jù)的功能,保存后的數(shù)據(jù),需要你用 perf report 解析展示。
$ perf record # 按Ctrl+C終止采樣 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.452 MB (6093 samples) ] $ perf report # 展示類似于perf top的報(bào)告

測試一下這個 Nginx 服務(wù)的性能

# 并發(fā)10個請求測試Nginx性能,總共測試100個請求 $ ab -c 10 -n 10000 This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, ... Requests per second: 11.63 [#/sec] (mean) Time per request: 859.942 [ms] (mean) ...

新開一個終端運(yùn)行 top 命令,并按下數(shù)字 1 ,切換到每個 CPU 的使用率:

$ top

怎么知道是 php-fpm 的哪個函數(shù)導(dǎo)致了 CPU 使用率升高呢?我們來用 perf 分析一下。在第一個終端運(yùn)行下面的 perf 命令:

# -g開啟調(diào)用關(guān)系分析,-p指定php-fpm的進(jìn)程號21515 $ perf top -g -p 21515

小結(jié)

CPU 使用率是最直觀和最常用的系統(tǒng)性能指標(biāo),更是我們在排查性能問題時(shí),通常會關(guān)注的第一個指標(biāo)。所以我們更要熟悉它的含義,尤其要弄清楚用戶(%user)、Nice(%nice)、系統(tǒng)(%system) 、等待 I/O(%iowait) 、中斷(%irq)以及軟中斷(%softirq)這幾種不同 CPU 的使用率。比如說:

  • 用戶 CPU 和 Nice CPU 高,說明用戶態(tài)進(jìn)程占用了較多的 CPU,所以應(yīng)該著重排查進(jìn)程的性能問題。
  • 系統(tǒng) CPU 高,說明內(nèi)核態(tài)占用了較多的 CPU,所以應(yīng)該著重排查內(nèi)核線程或者系統(tǒng)調(diào)用的性能問題。
  • I/O 等待 CPU 高,說明等待 I/O 的時(shí)間比較長,所以應(yīng)該著重排查系統(tǒng)存儲是不是出現(xiàn)了 I/O 問題。
  • 軟中斷和硬中斷高,說明軟中斷或硬中斷的處理程序占用了較多的 CPU,所以應(yīng)該著重排查內(nèi)核中的中斷服務(wù)程序。
    碰到 CPU 使用率升高的問題,你可以借助 top、pidstat 等工具,確認(rèn)引發(fā) CPU 性能問題的來源;再使用 perf 等工具,排查出引起性能問題的具體函數(shù)。思考


本文由博客一文多發(fā)平臺 發(fā)布!

1.《關(guān)于游戲cpu使用率100怎么辦,你需要知道這些某個應(yīng)用的CPU使用率居然達(dá)到100%,我該怎么辦?》援引自互聯(lián)網(wǎng),旨在傳遞更多網(wǎng)絡(luò)信息知識,僅代表作者本人觀點(diǎn),與本網(wǎng)站無關(guān),侵刪請聯(lián)系頁腳下方聯(lián)系方式。

2.《關(guān)于游戲cpu使用率100怎么辦,你需要知道這些某個應(yīng)用的CPU使用率居然達(dá)到100%,我該怎么辦?》僅供讀者參考,本網(wǎng)站未對該內(nèi)容進(jìn)行證實(shí),對其原創(chuàng)性、真實(shí)性、完整性、及時(shí)性不作任何保證。

3.文章轉(zhuǎn)載時(shí)請保留本站內(nèi)容來源地址,http://f99ss.com/gl/3195622.html