1. 程式人生 > >Linux之《荒島餘生》(二)CPU篇

Linux之《荒島餘生》(二)CPU篇

溫馨提示,動圖已壓縮,流量黨放心檢視。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執行棧,然後grep16進位制找到相應的資訊 錄個屏先

拔蘿蔔帶泥

但我想通過另外一種方式來實現這個功能(最多樣化),順便學幾個其他常用的命令。

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,上圖。 15423589014500.jpg

接下來,試著寫一下指令碼吧。

有哪些檢視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,果然是一個只有男人的世界!