作為一名后端程序員,應(yīng)該能經(jīng)常聽到“系統(tǒng)負(fù)載過高”,“CPU打爆了”諸如此類的描述,那么,什么是系統(tǒng)負(fù)載過高?什么是 CPU打爆了?生產(chǎn)環(huán)境,又該如何排查?今天我們就來聊一聊。遇到問題時,最重要的一環(huán)就是查看問題,下面分析 4個生產(chǎn)環(huán)境中會高頻使用的查詢指令。
一、如何查看負(fù)載
top 命令
top是使用最高頻的指令之一,命令及運行截圖如下:
# 系統(tǒng)默認(rèn)安裝的命令top

通過執(zhí)行指令可以看出:top 是交互式的系統(tǒng)監(jiān)視工具,實時顯示的信息特別多,主要包括下面幾類:
-
進程信息:
-
PID:進程id,唯一標(biāo)識進程
-
用戶:運行進程的用戶
-
CPU 使用率:進程正在使用的 CPU 資源的百分比
-
內(nèi)存使用率:進程正在使用的內(nèi)存的百分比
-
進程狀態(tài):進程的狀態(tài),如運行、休眠、停止等
-
進程優(yōu)先級:進程的優(yōu)先級
-
進程啟動時間:進程啟動的時間
-
-
系統(tǒng)總體性能:
-
系統(tǒng)平均負(fù)載:1分鐘、5分鐘和15分鐘的平均負(fù)載,用于表示系統(tǒng)的負(fù)載情況
-
總體 CPU使用率:系統(tǒng)的總體 CPU 使用率
-
總體內(nèi)存使用:系統(tǒng)的總體內(nèi)存使用情況,包括總內(nèi)存、空閑內(nèi)存、已使用內(nèi)存等信息
-
總體交換分區(qū)使用:如果有交換分區(qū),它的使用情況也會顯示
-
-
CPU 利用率:
-
按核心或邏輯處理器顯示每個 CPU 核心的使用情況,包括用戶態(tài)、系統(tǒng)態(tài)、空閑時間等
-
-
內(nèi)存和交換分區(qū)使用情況:
-
物理內(nèi)存:總物理內(nèi)存、已使用內(nèi)存、可用內(nèi)存、緩存和緩沖區(qū)等信息
-
交換分區(qū):總交換空間、已使用交換空間和可用交換空間
-
-
任務(wù)信息:
-
運行中的任務(wù)總數(shù)、運行任務(wù)數(shù)、睡眠任務(wù)數(shù)等
-
-
系統(tǒng)時間:
-
當(dāng)前系統(tǒng)時間以及系統(tǒng)運行時間
-
uptime 命令
top命令顯示的信息太多,如果想簡單的展示系統(tǒng)負(fù)載,uptime是比較匹配的命令,命令及運行截圖如下:
# 系統(tǒng)默認(rèn)安裝的命令uptime

通過截圖可以看出:uptime 命令只會顯示系統(tǒng)的平均負(fù)載以及系統(tǒng)當(dāng)前時間、已運行時間和登錄用戶數(shù)量 4個信息。
htop 命令
htop命令,系統(tǒng)默認(rèn)是不安裝的,所以在使用該命令時需要先安裝,命令和運行截圖如下:
# 系統(tǒng)默認(rèn)不安裝,需要自己安裝,比如:apt-get install htophtop

通過執(zhí)行指令可以看出:htop 和 top很類似,也是交互式的系統(tǒng)監(jiān)視工具,主要會顯示下面8種信息:
-
進程列表:htop 顯示當(dāng)前運行的所有進程的列表,包括它們的進程ID(PID)、用戶、進程狀態(tài)、CPU 使用率、內(nèi)存使用量等信息。這些信息按默認(rèn)情況下按 CPU 使用率降序排列。
-
CPU 和內(nèi)存利用情況:htop 在頂部顯示了一個可視化的 CPU 和內(nèi)存利用情況的圖形。這些圖形可以幫助你直觀地了解系統(tǒng)資源的使用情況。
-
系統(tǒng)負(fù)載信息:htop 在頂部的第一行顯示了系統(tǒng)的平均負(fù)載值,以及CPU核心的使用情況。這包括用戶態(tài)、系統(tǒng)態(tài)和等待態(tài)(I/O等待)的負(fù)載。
-
快捷鍵幫助:htop 在底部顯示了一些快捷鍵的幫助信息,以便用戶可以通過鍵盤快速執(zhí)行不同的操作,如終止進程、改變排序方式等。
-
進程樹:htop 可以顯示進程樹,這是一種以樹狀結(jié)構(gòu)展示進程之間關(guān)系的方式,有助于理解進程之間的父子關(guān)系。
-
進程狀態(tài)標(biāo)簽:htop 使用不同的顏色和標(biāo)簽來表示進程的狀態(tài),例如運行中的進程、休眠的進程、僵尸進程等,這有助于快速識別問題。
-
進程詳細(xì)信息:通過選中進程并按下鍵盤上的箭頭鍵或使用其他快捷鍵,htop 可以顯示有關(guān)選定進程的更詳細(xì)的信息,如打開的文件、線程信息、進程環(huán)境變量等。
-
可定制性:htop 允許用戶自定義顯示的列和排序方式,以滿足特定的監(jiān)視需求。
w 命令
w 命令和 uptime很類似,命令及運行截圖如下:
# 系統(tǒng)默認(rèn)安裝w
通過執(zhí)行指令可以看出:w 命令會顯示當(dāng)前登錄用戶的信息,包括平均負(fù)載。
通過執(zhí)行上面 4個指令,我們可以看出:每個指令的結(jié)果里面都包含“load averages:
數(shù)字1 數(shù)字2 數(shù)字3”, 那么 load averages是什么?后面的3個數(shù)字又代表什么含義?
二、平均負(fù)載
定義
load averages,中文翻譯為:平均負(fù)載,它是指在一段時間內(nèi)系統(tǒng)上運行的進程數(shù)量或等待資源的平均情況。通常用于 Unix 和類 Unix 系統(tǒng)。
定義看起來有些晦澀,其實,我們可以把平均負(fù)載簡單理解成平均活躍進程數(shù)。
三個重要數(shù)字
介紹了平均負(fù)載的定義,接著分析 load averages 后面三個重要數(shù)字的含義,通過執(zhí)行 man uptime指令,我們可以查看官方文檔:
# 系統(tǒng)默認(rèn)安裝的命令man uptime
從文檔截圖可以總結(jié)三個數(shù)字的含義分別為:
-
1分鐘平均負(fù)載: 表示在最近1分鐘內(nèi)系統(tǒng)的平均負(fù)載情況;
-
5分鐘平均負(fù)載: 表示在最近5分鐘內(nèi)系統(tǒng)的平均負(fù)載情況;
-
15分鐘平均負(fù)載: 表示在最近15分鐘內(nèi)系統(tǒng)的平均負(fù)載情況;
解釋完 load averages 3個數(shù)字的含義,另一個問題也就隨之而來:3個數(shù)字的值為多少代表系統(tǒng)健康?多少代表系統(tǒng)過載了?在解答這個問題之前,我們先來分析“CPU打爆了”。
三、CPU打爆了
CPU打爆了,其實就是說 CPU的使用率大于等于100%,比如,如果服務(wù)器只有一個 CPU,100% 就代表 CPU滿負(fù)載,如果服務(wù)器有 2個 CPU,那么 CPU的使用率 >= 200%,CPU就被打爆了, 在生產(chǎn)環(huán)境,通常會把CPU總量的 80%~85%設(shè)置為報警閾值,這樣就能提醒相關(guān)人員服務(wù)器的 CPU使用過高,需要特別關(guān)注。
那么,如何查看服務(wù)器的 CPU個數(shù)呢?可以使用下面的指令:
# linux 查看CPU個數(shù)grep 'model name' /proc/cpuinfo | wc -l# mac 查看CPU個數(shù)sysctl -n hw.physicalcpu
如下圖:


四、兩者關(guān)系
分析了平均負(fù)載和 CPU使用率,那么兩者之間存在什么關(guān)系呢?
在平均負(fù)載定義時提到平均負(fù)載就是進程平均數(shù),因此,先來看看進程是什么:
進程是指計算機上運行的程序?qū)嵗ǔ0?CPU密集型進程 和 IO密集型進程,兩種進程的詳情如下:
-
CPU密集型進程:
-
特點:CPU密集型進程是那些主要依賴于處理器執(zhí)行能力的任務(wù)。它們通常涉及大量的計算、數(shù)據(jù)處理和算法運算,需要大量的 CPU時間來完成。
-
資源需求:這種類型的進程主要消耗 CPU資源,而對內(nèi)存和磁盤等其他資源的需求相對較低。
-
性能特點:CPU密集型進程在多核處理器上執(zhí)行時,可以受益于并行計算,因為它們可以同時在多個CPU核心上運行。提高CPU頻率和核心數(shù)量可以顯著提高這些進程的性能。
-
示例:數(shù)值模擬、圖像處理、密碼破解等計算密集型任務(wù)。
-
IO密集型進程:
-
特點:IO密集型進程是那些主要涉及文件讀寫、網(wǎng)絡(luò)通信、數(shù)據(jù)庫查詢等需要大量IO操作的任務(wù)。它們通常不需要大量的CPU計算時間,而是花費大部分時間等待IO操作完成。
-
資源需求:IO密集型進程對 CPU的需求相對較低,但對存儲設(shè)備、網(wǎng)絡(luò)和內(nèi)存等IO相關(guān)資源的需求較高。
-
性能特點:提高 CPU性能對 IO密集型任務(wù)的影響有限,因為它們通常受限于IO操作的速度。使用異步IO、多線程或多進程等技術(shù)可以提高IO密集型進程的性能。
-
示例:Web服務(wù)器、數(shù)據(jù)庫服務(wù)器、文件上傳下載服務(wù)等需要頻繁IO操作的應(yīng)用程序。
到此,我們可以給平均負(fù)載重新定義,它是指系統(tǒng)中 IO密集型進程和 CPU密集型進程的平均數(shù)。這樣是不是對平均負(fù)載有更好的理解。
而 CPU作為中央處理單元,它是執(zhí)行系統(tǒng)中各種進程的硬件。假如每個 CPU上剛好有且只有一個進程在運行,是不是意味著不用切換 CPU,每個進程享受著 CPU 1對1的服務(wù)。因此,如果平均負(fù)載等于 CPU個數(shù),就剛好滿足了這種 1對1服務(wù),所以,平均負(fù)載最理想的情況就是等于 CPU個數(shù)。
有了這個前提,可以得出:在單 CPU服務(wù)器上 load averages 1 1 1 是最理想的平均負(fù)載,同理,在 N個 CPU的服務(wù)器上 load averages N N N 是最理想的平均負(fù)載。
如果 平均負(fù)載的3個數(shù)字不等于 CPU個數(shù),就代表負(fù)載不正常嗎?下面我們分析一個案例:單 CPU服務(wù)器 load averages 0.6 1.2 0.8。
1分鐘平均負(fù)載為0.6, 小于1, 屬于低負(fù)載,5分鐘平均負(fù)載為1.2,大于1,系統(tǒng)過載,15分鐘平均負(fù)載為0.8, 也是低負(fù)載。平均負(fù)載對整體走勢是: 從 15分鐘的0.8 升高到 5分鐘的 1.2, 因此系統(tǒng)服務(wù)在升高,但又從 5分鐘的1.2 降到 1分鐘的0.6, 說明服務(wù)器的負(fù)載在降低,最后正常,所以對于 load averages,我們應(yīng)該按照整個發(fā)展趨勢來分析,這樣才能更好的分析系統(tǒng)的負(fù)載變化。趨勢可以參考下面對手繪圖:

那么,生產(chǎn)環(huán)境,平均負(fù)載多少是合理的?
業(yè)內(nèi)經(jīng)驗值:小于 CPU總數(shù)的 70% 是正常的,超過 70% 就需特別注意。但這個值并不是絕對的,需要根據(jù)具體業(yè)務(wù)具體分析。
最后,平均負(fù)載高,CPU就一定高嗎?
在講解進程時提到進程有 CPU密集型和 IO密集型,而 IO密集型對 CPU的影響不大,所以,平均負(fù)載高,CPU不一定高。
因此,在生產(chǎn)排查時,如果發(fā)現(xiàn)負(fù)載高,CPU使用率高,那任務(wù)是 CPU密集型概率比較大;如果發(fā)現(xiàn)負(fù)載高,CPU使用率不是很高,那任務(wù)是 IO密集型概率比較大。
五、CPU飆高排查過程
CPU飆高排查,應(yīng)該是對很多后端程序員的一個能力要求,下面給出了一個常用的排查步驟:
-
連接到問題服務(wù)器;
-
執(zhí)行 top命令:查找 CPU使用最高的進程PID;
-
執(zhí)行 jstack > t.log 命令:導(dǎo)出線程堆棧;
-
執(zhí)行 top -pH pid:查看進程所有線程的 CPU使用率以及線程Id;
-
執(zhí)行 printf %x 線程pid:將線程ID轉(zhuǎn)換成16進制ID,并在步驟3中生成的線程堆棧里找到對應(yīng)的線程;
-
根據(jù)堆棧信息,找到對應(yīng)源碼分析具體原因;
六、總結(jié)
-
本文介紹了 4個生產(chǎn)環(huán)境常用的系統(tǒng)負(fù)載排查指令:top,uptime,htop,w;
-
本文分析了平均負(fù)載是什么,以及如何分析負(fù)載的3個重要數(shù)字;
-
本文分析了平均負(fù)載和 CPU的關(guān)系:平均負(fù)載理想值等于 CPU數(shù);
-
進程分 CPU密集型和 IO密集型, 對于 CPU密集型進程,負(fù)載高,CPU也隨著升高;IO密集型進程,負(fù)載高,CPU不一定高;
-
文末給出了生產(chǎn)環(huán)境 CPU飆高的排查過程;







