CPU load過高產(chǎn)生的原因及排查
之前面試被問到,造成CPU load過高的原因有哪些?如何快速排查其原因?
什么是cpu load 值
top命令中顯示的load average即為最近1分鐘、5分鐘和15分鐘的系統(tǒng)平均負(fù)載。

系統(tǒng)平均負(fù)載被定義為在特定時(shí)間間隔內(nèi)運(yùn)行隊(duì)列中(在CPU上運(yùn)行或者等待運(yùn)行多少進(jìn)程)的平均進(jìn)程數(shù)。如果一個(gè)進(jìn)程滿足以下條件則其就會(huì)位于運(yùn)行隊(duì)列中:
它沒有在等待I/O操作的結(jié)果
它沒有主動(dòng)進(jìn)入等待狀態(tài)(也就是沒有調(diào)用’wait’)
沒有被停止(例如:等待終止)
在Linux中,進(jìn)程分為三種狀態(tài),一種是阻塞的進(jìn)程blocked process(等待I/O設(shè)備的數(shù)據(jù)或者系統(tǒng)調(diào)),一種是可運(yùn)行的進(jìn)程runnable process,另外就是正在運(yùn)行的進(jìn)程running process。
進(jìn)程可運(yùn)行狀態(tài)時(shí),它處在一個(gè)運(yùn)行隊(duì)列run queue中,與其他可運(yùn)行進(jìn)程爭(zhēng)奪CPU時(shí)間。系統(tǒng)的load是指正在運(yùn)行和準(zhǔn)備好運(yùn)行的進(jìn)程的總數(shù)。比如現(xiàn)在系統(tǒng)有2個(gè)正在運(yùn)行的進(jìn)程,3個(gè)可運(yùn)行進(jìn)程,那么系統(tǒng)的load就是5。load average就是一定時(shí)間內(nèi)的load數(shù)量。
什么因素構(gòu)成了cpu load的大小
衡量CPU 系統(tǒng)負(fù)載的指標(biāo)是load,load 就是對(duì)計(jì)算機(jī)系統(tǒng)能夠承擔(dān)的多少負(fù)載的度量,簡(jiǎn)單的說是進(jìn)程隊(duì)列的長(zhǎng)度。請(qǐng)求大于當(dāng)前的處理能力,會(huì)出現(xiàn)等待,引起load升高。
對(duì)于本文剛剛開頭顯示的 load average 0.21 0.10 0.03
很多人會(huì)這樣理解負(fù)載均值:三個(gè)數(shù)分別代表不同時(shí)間段的系統(tǒng)平均負(fù)載(一分鐘、五 分鐘、以及十五分鐘),它們的數(shù)字當(dāng)然是越小越好。數(shù)字越高,說明服務(wù)器的負(fù)載越大,這也可能是服務(wù)器出現(xiàn)某種問題的信號(hào)。而事實(shí)不完全如此,是什么因素構(gòu)成了負(fù)載均值的大小,以及如何區(qū)分它們目前的狀況是 “好”還是“糟糕”?什么時(shí)候應(yīng)該注意哪些不正常的數(shù)值?
回答這些問題之前,首先需要了解下這些數(shù)值背后的些知識(shí)。我們先用最簡(jiǎn)單的例子說明, 一臺(tái)只配備一塊單核處理器的服務(wù)器。
行車過橋
一只單核的處理器可以形象得比喻成一條單車道。設(shè)想下,你現(xiàn)在需要收取這條道路的過橋費(fèi) — 忙于處理那些將要過橋的車輛。你首先當(dāng)然需要了解些信息,例如車輛的載重、以及 還有多少車輛正在等待過橋。如果前面沒有車輛在等待,那么你可以告訴后面的司機(jī)通過。如果車輛眾多,那么需要告知他們可能需要稍等一會(huì)。
因此,需要些特定的代號(hào)表示目前的車流情況,例如:
0.00 表示目前橋面上沒有任何的車流。實(shí)際上這種情況與 0.00 和 1.00 之間是相同的,總而言之很通暢,過往的車輛可以絲毫不用等待的通過。
1.00 表示剛好是在這座橋的承受范圍內(nèi)。這種情況不算糟糕,只是車流會(huì)有些堵,不過這種情況可能會(huì)造成交通越來(lái)越慢。
超過 1.00,那么說明這座橋已經(jīng)超出負(fù)荷,交通嚴(yán)重的擁堵。那么情況有多糟糕? 例如 2.00 的情況說明車流已經(jīng)超出了橋所能承受的一倍,那么將有多余過橋一倍的車輛正在焦急的等待。3.00 的話情況就更不妙了,說明這座橋基本上已經(jīng)快承受不了,還有超出橋負(fù)載兩倍多的車輛正在等待。
上面的情況和處理器的負(fù)載情況非常相似。一輛汽車的過橋時(shí)間就好比是處理器處理某線程 的實(shí)際時(shí)間。Unix 系統(tǒng)定義的進(jìn)程運(yùn)行時(shí)長(zhǎng)為所有處理器內(nèi)核的處理時(shí)間加上線程在隊(duì)列中等待的時(shí)間。
和收過橋費(fèi)的管理員一樣,你當(dāng)然希望你的汽車(操作)不會(huì)被焦急的等待。所以,理想狀態(tài) 下,都希望負(fù)載平均值小于 1.00 。當(dāng)然不排除部分峰值會(huì)超過 1.00,但長(zhǎng)此以往保持這 個(gè)狀態(tài),就說明會(huì)有問題,這時(shí)候你應(yīng)該會(huì)很焦急。
“所以你說的理想負(fù)荷為 1.00 ?”嗯,這種情況其實(shí)并不完全正確。負(fù)荷 1.00 說明系統(tǒng)已經(jīng)沒有剩余的資源了。在實(shí)際情況中 ,有經(jīng)驗(yàn)的系統(tǒng)管理員都會(huì)將這條線劃在 0.70。如果長(zhǎng)期你的系統(tǒng)負(fù)載在 0.70 上下,那么你需要在事情變得更糟糕之前,花些時(shí)間了解其原因。
多核處理器: 系統(tǒng)還是以處理器的核心數(shù)量計(jì)算負(fù)載均值
在多核處理中,你的系統(tǒng)均值不應(yīng)該高于處理器核心的總數(shù)量。繼續(xù)針對(duì)上述的汽車過橋問題,如果是雙核CPU,那么負(fù)載在2.0才是負(fù)載滿額。如下是對(duì)于雙核處理器的輸出。
uptime17:57 up 22 days, 8:29, 3 users, load averages: 2.04 2.04 2.01
cpu load 過高原因以及排查
造成cpu load過高的原因.從編程語(yǔ)言層次上full gc次數(shù)的增大或死循環(huán)都有可能造成cpu load 增高
具體的排查一句話描述就是
首先要找到哪幾個(gè)線程在占用cpu,之后再通過線程的id值在堆棧文件中查找具體的線程,看看出來(lái)什么問題。
尋找最占CPU的進(jìn)程
通過命令 ps ux
通過top -c命令顯示進(jìn)程運(yùn)行信息列表 (按鍵P按CPU占有資源排序)
尋找最耗CPU的線程
top -Hp 進(jìn)程ID 顯示一個(gè)進(jìn)程ID的線程運(yùn)行信息列表 (按鍵P按CPU占有資源排序)
如果該進(jìn)程是java進(jìn)程,需要具體查看是哪段代碼造成的CPU負(fù)載過高,根據(jù)上述獲得到的線程ID可以使用JDK下的jstack來(lái)查看堆棧。
版權(quán)聲明:本文為CSDN博主「不能說的秘密go」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。原文鏈接:https://blog.csdn.net/canot/article/details/78079085
