為什么80%的碼農都做不了架構師?>>> ??
溫馨提示,動圖已壓縮,流量黨放心查看。CPU方面內容不多,我們順便學點命令。本篇是《荒島余生》系列第二篇,垂直觀測CPU。其余參見:
Linux之《荒島余生》(一)準備篇
如何做一個CPU
cpu是芯片的一種,我們以漢芯為例,看一下制作七步曲。
? 提純精度11個9的硅片(99.999999999%)
? 生成晶圓
? 使用光刻機加工晶圓
? 使用刻蝕機溝槽
? 完成P型半導體制作
? 使用200號的粗砂紙抹掉原標志
? 涂上新標志
bingo,完工!
雖然CPU很小,但生產它的設備可不簡單。如下圖,就是一臺重十幾噸,占地上百平米,全世界都當寶貝的光刻機!
你我就這樣飽受科技的恩澤,有時間探討在中央處理器上發生的故事了。
找到占用CPU最高的線程
接下來看一個實際的例子。公司有點窮,所以機器上混合部署了多個java應用,突然有一天,CPU炸了,我們要找到是誰引起的。這個誰不是進程,而是線程,離真相最近的那個。
傳統做法
通常的做法是:
? 在命令行輸入top
,然后shift+p
查看占用CPU最高的進程,記下進程號
? 在命令行輸入top -Hp 進程號
,查看占用CPU最高的線程
? 使用printf 0x%x 線程號
,得到其16進制線程號
? 使用jstack 進程號
得到java執行棧,然后grep
16進制找到相應的信息
錄個屏先
拔蘿卜帶泥
但我想通過另外一種方式來實現這個功能(最多樣化),順便學幾個其他常用的命令。
ps -eo %cpu,pid |sort -n -k1 -r | head -n 1 | ?awk '{print $2}' |xargs ?top -b -n1 -Hp | grep COMMAND -A1 | tail -n 1 | awk '{print $1}' | xargs printf 0x%x
這一行Shell的意思是,找到使用CPU最高的進程之使用CPU最高的線程的16進制號。
這么長的命令,是不是暈了?別怕,我們一點點來。通常情況下,練習熟練了命令中出現的這幾個,就能夠應對50%的常用工作了。Come on,上圖。
接下來,試著寫一下腳本吧。
有哪些查看CPU的命令
top
其實從上面命令就可以瞧出來,top和ps的命令是互通的,只不過表現形式不同,我們直接拿top來說。按數字1就可以顯示每核CPU的使用情況。基本上都是些單詞的縮寫,看幾遍就忘不掉了。比如 :
us ==> user CPU time
先記住這些判斷準則,我們在示例中再聊:
? 如果load超過了cpu核數,則負載過高
? 如果wa過高,可初步判斷I/O有問題
? sy,si,hi,st,任何一個超過5%,都有問題
? 進程狀態長時處于D、Z、T狀態,提高注意度
? cpu不均衡,判斷親和性和優先級問題
vmstat
vmstat 以另一種形式來展示一些信息。如圖:
除了關注類似top的一些指標,還有:
??b
?置于等待隊列(等待資源、等待輸入/輸出)的內核線程數目。數字過大則cpu太忙。
??cs
?如果頻繁的進行上下文切換,則考慮是否是線程數開的過多
??si
/so
?顯示了交換分區的現狀,有時候會造成cpu問題,一并關注
sar
是目前Linux上最為全面的系統性能分析工具之一,但可能沒有預裝。在centos上使用以下命令即可安裝。
yum install sysstat -y
sar主要的好處是可以看到歷史,顯示友好,可以對結果進行二次處理。sar還有圖形化工具,執行sar -A
即可獲得所有數據。
https://github.com/vlsi/ksar
針對于CPU方面,我們關注:
? sar -u ?默認
? sar -P ALL 每顆cpu的使用狀態信息
? sar -q ?cpu隊列的長度,runq-sz>cpu count就表明有瓶頸了
? sar -w ?每秒上下文交換
可以瞧見,關注的也就那幾個點而已。
mpstat
還有pidstat
,包括彩色的dstat
,功能都差不多, 用熟一個就ok了。
數據從何而來
那么數據從何而來?/proc
目錄是一個虛擬目錄,存儲的是當前內核的一系列特殊文件,你不僅能查看一些狀態,甚至能修改一些值來改變系統的行為。
比如top的load (使用uptime命令得到同樣的結果)。讀取的就是/proc/loadavg
?文件
而每核cpu的信息,讀取/proc/stat
文件
這些命令,是對/proc目錄中一系列信息的解析和友好的展示,這些值,Linux內核都算好了躺在那呢。
(圖片來源網絡)
創建這個目錄的人真是天才!
幾個例子
CPU過高是表象。除了系統確實負載已經到了極限,其他的,都是由其他原因引起的,比如I/O;比如設備。這些我們放在其他章節進行討論。
GC引起的CPU過高
接著我們最開始的例子來。通過查看jstack找到相應的16進制進程,結果發現是GC線程。
"VM Thread" prio=10 tid=0x00007f06d8089000 nid=0x58c7 runnable "GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f06d801b800 nid=0x58d7 runnable
這種情況,一般都是JVM內存不夠用了,瘋狂GC,可能是socket/線程忘了關閉了,也可能是大對象沒有回收。這種情況只能通過重啟來解決了,記得重啟之前,使用jmap dump一下堆棧哦。當然,你可能會得到jdk版本的問題。
st%占比過高
st過高一般是物理CPU資源不足所致,也就是只發生在虛擬機上。
如果你買的虛擬機st一直很高,那你的服務提供商可能在超賣,擠占你的資源。不信雙11的時候看下你的虛擬機?
網卡導致單cpu過高
業務方幾臺kafka,cpu使用處于正常水平,才10%左右,但有一核cpu,負載特別的高,si奇高。
mpstat -I SUM -P ALL 查看cpu使用情況,cpu0的中斷確實比較多。
20:15:18 ?CPU ? ?intr/s ?
20:15:23 ?all ?34234.20 ?
20:15:23 ? ?0 ? 9566.20 ?
20:15:23 ? ?1 ? ? ?0.00
網卡需要cpu服務時,都會拋出一個中斷,中斷告訴cpu發生了什么事情,cpu就要停止目前的工作來處理這個中斷。其實,默認所有的中斷處理都集中在cpu0 上,導致服務器負載過高。cpu0 成了瓶頸,而其他cpu卻還閑著。
? 解決方式1:使用CPU親和性功能,kafka略過網卡所使用的CPU
? 解決方式2: 更換網卡
? 通常修改的方式還是有些復雜了,比如,修改
/proc/irq/{seq}/smp_affinity
我們可以直接安裝irqbalance
,然后執行就可以了。
yum install irqbalance -y
service irqbalance start
cpu使用率低,但負載高
cpu id%高,也就是空閑,比如90%。但 load average非常高,比如4核達到10。
分析:load average高,說明其任務已經排隊,許多任務正在等待。出現此種情況,可能存在大量不可中斷的進程。
使用top或者ps可以看到進程相應的狀態。
ps aux
一種情況就是有大量進程處于D的狀態,也就是不可中斷的睡眠狀態,所以很可能是硬件問題。
詳見《Linux進程狀態(ps stat)之R、S、D、T、Z、X》
高頻問題:load
load代表的是啥
說句白話,load代表的就是你目前系統進程的排隊情況。
如圖,以單核為例,將CPU資源抽象成一條單行馬路。則會發生三種情況:
? 馬路上的車只有4輛,車輛暢通無阻,load大約是0.5
? 馬路上的車有8輛,正好能首尾相接安全通過,此時load大約為1
? 馬路上的車有12輛,除了在馬路上的8輛車,還有4輛交集的等在外面,也就是超出容量了,需要排隊。此時load大約為1.5
load為1代表的是啥
針對這個問題,誤解還是比較多的。很多同學認為,load達到1,系統就到了瓶頸,這不完全正確。
load的值和cpu核數息息相關:
? 單核的cpu達到100%,load約1
? 雙核的cpu都達到100%,load約2
? 四核的cpu都達到100%,load約為4
所以,對于一個load到了10,卻是16核的機器,你的系統還遠沒有達到負載極限。
結尾
此文歸屬「小姐姐味道」,轉載注明出處。本篇實際的排查過程較少,因為cpu問題一般都伴隨著其他問題。但文中出現的這些命令可不簡單,尤其是它們豐富的參數。這些參數,執行一下man,就可以一睹芳容了。比如:
man top
當然,也可以這樣~
no woman、 no love,果然是一個只有男人的世界!