作為一名后端程序員,應該能經常聽到“系統負載過高”,“CPU打爆了”諸如此類的描述,那么,什么是系統負載過高?什么是 CPU打爆了?生產環境,又該如何排查?今天我們就來聊一聊。遇到問題時,最重要的一環就是查看問題,下面分析 4個生產環境中會高頻使用的查詢指令。
一、如何查看負載
top 命令
top是使用最高頻的指令之一,命令及運行截圖如下:
# 系統默認安裝的命令
top
通過執行指令可以看出:top 是交互式的系統監視工具,實時顯示的信息特別多,主要包括下面幾類:
-
進程信息:
-
PID:進程id,唯一標識進程
-
用戶:運行進程的用戶
-
CPU 使用率:進程正在使用的 CPU 資源的百分比
-
內存使用率:進程正在使用的內存的百分比
-
進程狀態:進程的狀態,如運行、休眠、停止等
-
進程優先級:進程的優先級
-
進程啟動時間:進程啟動的時間
-
-
系統總體性能:
-
系統平均負載:1分鐘、5分鐘和15分鐘的平均負載,用于表示系統的負載情況
-
總體 CPU使用率:系統的總體 CPU 使用率
-
總體內存使用:系統的總體內存使用情況,包括總內存、空閑內存、已使用內存等信息
-
總體交換分區使用:如果有交換分區,它的使用情況也會顯示
-
-
CPU 利用率:
-
按核心或邏輯處理器顯示每個 CPU 核心的使用情況,包括用戶態、系統態、空閑時間等
-
-
內存和交換分區使用情況:
-
物理內存:總物理內存、已使用內存、可用內存、緩存和緩沖區等信息
-
交換分區:總交換空間、已使用交換空間和可用交換空間
-
-
任務信息:
-
運行中的任務總數、運行任務數、睡眠任務數等
-
-
系統時間:
-
當前系統時間以及系統運行時間
-
uptime 命令
top命令顯示的信息太多,如果想簡單的展示系統負載,uptime是比較匹配的命令,命令及運行截圖如下:
# 系統默認安裝的命令
uptime
通過截圖可以看出:uptime 命令只會顯示系統的平均負載以及系統當前時間、已運行時間和登錄用戶數量 4個信息。
htop 命令
htop命令,系統默認是不安裝的,所以在使用該命令時需要先安裝,命令和運行截圖如下:
# 系統默認不安裝,需要自己安裝,比如:apt-get install htop
htop
通過執行指令可以看出:htop 和 top很類似,也是交互式的系統監視工具,主要會顯示下面8種信息:
-
進程列表:htop 顯示當前運行的所有進程的列表,包括它們的進程ID(PID)、用戶、進程狀態、CPU 使用率、內存使用量等信息。這些信息按默認情況下按 CPU 使用率降序排列。
-
CPU 和內存利用情況:htop 在頂部顯示了一個可視化的 CPU 和內存利用情況的圖形。這些圖形可以幫助你直觀地了解系統資源的使用情況。
-
系統負載信息:htop 在頂部的第一行顯示了系統的平均負載值,以及CPU核心的使用情況。這包括用戶態、系統態和等待態(I/O等待)的負載。
-
快捷鍵幫助:htop 在底部顯示了一些快捷鍵的幫助信息,以便用戶可以通過鍵盤快速執行不同的操作,如終止進程、改變排序方式等。
-
進程樹:htop 可以顯示進程樹,這是一種以樹狀結構展示進程之間關系的方式,有助于理解進程之間的父子關系。
-
進程狀態標簽:htop 使用不同的顏色和標簽來表示進程的狀態,例如運行中的進程、休眠的進程、僵尸進程等,這有助于快速識別問題。
-
進程詳細信息:通過選中進程并按下鍵盤上的箭頭鍵或使用其他快捷鍵,htop 可以顯示有關選定進程的更詳細的信息,如打開的文件、線程信息、進程環境變量等。
-
可定制性:htop 允許用戶自定義顯示的列和排序方式,以滿足特定的監視需求。
w 命令
w 命令和 uptime很類似,命令及運行截圖如下:
# 系統默認安裝
w
通過執行指令可以看出:w 命令會顯示當前登錄用戶的信息,包括平均負載。
通過執行上面 4個指令,我們可以看出:每個指令的結果里面都包含“load averages:
數字1 數字2 數字3”, 那么 load averages是什么?后面的3個數字又代表什么含義?
二、平均負載
定義
load averages,中文翻譯為:平均負載,它是指在一段時間內系統上運行的進程數量或等待資源的平均情況。通常用于 Unix 和類 Unix 系統。
定義看起來有些晦澀,其實,我們可以把平均負載簡單理解成平均活躍進程數。
三個重要數字
介紹了平均負載的定義,接著分析 load averages 后面三個重要數字的含義,通過執行 man uptime指令,我們可以查看官方文檔:
# 系統默認安裝的命令
man uptime
從文檔截圖可以總結三個數字的含義分別為:
-
1分鐘平均負載: 表示在最近1分鐘內系統的平均負載情況;
-
5分鐘平均負載: 表示在最近5分鐘內系統的平均負載情況;
-
15分鐘平均負載: 表示在最近15分鐘內系統的平均負載情況;
解釋完 load averages 3個數字的含義,另一個問題也就隨之而來:3個數字的值為多少代表系統健康?多少代表系統過載了?在解答這個問題之前,我們先來分析“CPU打爆了”。
三、CPU打爆了
CPU打爆了,其實就是說 CPU的使用率大于等于100%,比如,如果服務器只有一個 CPU,100% 就代表 CPU滿負載,如果服務器有 2個 CPU,那么 CPU的使用率 >= 200%,CPU就被打爆了, 在生產環境,通常會把CPU總量的 80%~85%設置為報警閾值,這樣就能提醒相關人員服務器的 CPU使用過高,需要特別關注。
那么,如何查看服務器的 CPU個數呢?可以使用下面的指令:
# linux 查看CPU個數
grep 'model name' /proc/cpuinfo | wc -l
# mac 查看CPU個數
sysctl -n hw.physicalcpu
如下圖:
四、兩者關系
分析了平均負載和 CPU使用率,那么兩者之間存在什么關系呢?
在平均負載定義時提到平均負載就是進程平均數,因此,先來看看進程是什么:
進程是指計算機上運行的程序實例,通常包含 CPU密集型進程 和 IO密集型進程,兩種進程的詳情如下:
-
CPU密集型進程:
-
特點:CPU密集型進程是那些主要依賴于處理器執行能力的任務。它們通常涉及大量的計算、數據處理和算法運算,需要大量的 CPU時間來完成。
-
資源需求:這種類型的進程主要消耗 CPU資源,而對內存和磁盤等其他資源的需求相對較低。
-
性能特點:CPU密集型進程在多核處理器上執行時,可以受益于并行計算,因為它們可以同時在多個CPU核心上運行。提高CPU頻率和核心數量可以顯著提高這些進程的性能。
-
示例:數值模擬、圖像處理、密碼破解等計算密集型任務。
-
IO密集型進程:
-
特點:IO密集型進程是那些主要涉及文件讀寫、網絡通信、數據庫查詢等需要大量IO操作的任務。它們通常不需要大量的CPU計算時間,而是花費大部分時間等待IO操作完成。
-
資源需求:IO密集型進程對 CPU的需求相對較低,但對存儲設備、網絡和內存等IO相關資源的需求較高。
-
性能特點:提高 CPU性能對 IO密集型任務的影響有限,因為它們通常受限于IO操作的速度。使用異步IO、多線程或多進程等技術可以提高IO密集型進程的性能。
-
示例:Web服務器、數據庫服務器、文件上傳下載服務等需要頻繁IO操作的應用程序。
到此,我們可以給平均負載重新定義,它是指系統中 IO密集型進程和 CPU密集型進程的平均數。這樣是不是對平均負載有更好的理解。
而 CPU作為中央處理單元,它是執行系統中各種進程的硬件。假如每個 CPU上剛好有且只有一個進程在運行,是不是意味著不用切換 CPU,每個進程享受著 CPU 1對1的服務。因此,如果平均負載等于 CPU個數,就剛好滿足了這種 1對1服務,所以,平均負載最理想的情況就是等于 CPU個數。
有了這個前提,可以得出:在單 CPU服務器上 load averages 1 1 1 是最理想的平均負載,同理,在 N個 CPU的服務器上 load averages N N N 是最理想的平均負載。
如果 平均負載的3個數字不等于 CPU個數,就代表負載不正常嗎?下面我們分析一個案例:單 CPU服務器 load averages 0.6 1.2 0.8。
1分鐘平均負載為0.6, 小于1, 屬于低負載,5分鐘平均負載為1.2,大于1,系統過載,15分鐘平均負載為0.8, 也是低負載。平均負載對整體走勢是: 從 15分鐘的0.8 升高到 5分鐘的 1.2, 因此系統服務在升高,但又從 5分鐘的1.2 降到 1分鐘的0.6, 說明服務器的負載在降低,最后正常,所以對于 load averages,我們應該按照整個發展趨勢來分析,這樣才能更好的分析系統的負載變化。趨勢可以參考下面對手繪圖:
那么,生產環境,平均負載多少是合理的?
業內經驗值:小于 CPU總數的 70% 是正常的,超過 70% 就需特別注意。但這個值并不是絕對的,需要根據具體業務具體分析。
最后,平均負載高,CPU就一定高嗎?
在講解進程時提到進程有 CPU密集型和 IO密集型,而 IO密集型對 CPU的影響不大,所以,平均負載高,CPU不一定高。
因此,在生產排查時,如果發現負載高,CPU使用率高,那任務是 CPU密集型概率比較大;如果發現負載高,CPU使用率不是很高,那任務是 IO密集型概率比較大。
五、CPU飆高排查過程
CPU飆高排查,應該是對很多后端程序員的一個能力要求,下面給出了一個常用的排查步驟:
-
連接到問題服務器;
-
執行 top命令:查找 CPU使用最高的進程PID;
-
執行 jstack > t.log 命令:導出線程堆棧;
-
執行 top -pH pid:查看進程所有線程的 CPU使用率以及線程Id;
-
執行 printf %x 線程pid:將線程ID轉換成16進制ID,并在步驟3中生成的線程堆棧里找到對應的線程;
-
根據堆棧信息,找到對應源碼分析具體原因;
六、總結
-
本文介紹了 4個生產環境常用的系統負載排查指令:top,uptime,htop,w;
-
本文分析了平均負載是什么,以及如何分析負載的3個重要數字;
-
本文分析了平均負載和 CPU的關系:平均負載理想值等于 CPU數;
-
進程分 CPU密集型和 IO密集型, 對于 CPU密集型進程,負載高,CPU也隨著升高;IO密集型進程,負載高,CPU不一定高;
-
文末給出了生產環境 CPU飆高的排查過程;