天天看點

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

(1)<code>grep 'model name' /proc/cpuinfo|wc -l</code>

(2)<code>grep 'core id' /proc/cpuinfo|wc -l</code>

(1)<code>centos:yum install -y stress sysstat</code>

(2)<code>ubuntu:apt install stress sysstat</code>

(1)壓測cpu:<code>stress --cpu 1 --timeout 600</code>

(2)檢視系統平均負載的變化:<code>watch -d uptime</code> (-d 表示高亮顯示變化的區域)

(3)檢視系統cpu使用率的變化情況:<code>mpstat -P ALL 5</code> (-P ALL 表示監控所有的cpu,後面的數字5表示間隔5秒輸出一組資料)動态的輸出

(4)檢視系統程序使用cpu情況:<code>pidstat -u 5 2</code> (-u表示每隔5秒輸出一組資料,總共輸出兩次,并列印出平均數值)

壓測IO:<code>stress --io 1 --timeout 600</code>

過程如情景一

模拟8個程序:<code>stress --cpu 8 --timeout 600</code>

檢視上下文切換:<code>vmstat 5</code>(每隔5秒輸出1組資料)

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

(1)<code>cs(context switch)</code>就是每秒上下文切換的次數

(2)<code>in(interrupt)</code>每秒中斷的次數

(3)<code>r(running or runnable)</code>表示就緒隊列的長度,也就是正在運作和等待CPU的程序數

(4)<code>b(blocked)</code>表示處于不可中斷睡眠狀态的程序數

檢視詳細上下文切換的情況:<code>pidstat -w 5</code>(每隔5秒輸出1組資料,動态的)

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

(1)<code>cswch</code>表示每秒自願上下文切換(voluntary context switches)的次數

(2)<code>nvcswch</code>表示每秒非自願上下文切換(non voluntary context switches)的次數

上下文切換概念:

(1)自願上下文切換:指程序無法擷取所需資源,導緻的上下文切換。比如,I/O,記憶體等系統資源不足時;

(2)非自願上下文切換:指程序由于時間片已到等原因,被系統強制排程,進而發生的上下文切換。比如,大量程序都在争搶CPU時;

模拟多線程排程:

(1)<code>centos:yum install -y sysbench</code>

(2)<code>ubuntu:apt install sysbench</code>

測試:

(1)以10個線程運作5分鐘的基準測試,模拟系統多線程切換的問題:<code>sysbench --threads=10 --max-time=300 threads run</code>

(2)觀察上下文切換情況:<code>vmstat 1</code>

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

(3)檢視cpu和上下文切換的程序和線程情況:<code>pidstat -w -u 1</code>

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

系統的就緒隊列過長,也就是正在運作和等待cpu的程序數過多,導緻大量的上下文切換,而上下文切換又導緻了系統cpu的占用率升高。

(4)上圖中pidstat 預設顯示程序的名額資料,加上<code>-t</code>參數後,才會輸出線程的名額。

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

(5)查找源頭,注意中斷次數,是什麼類型的中斷上升呢:<code>watch -d cat /proc/interrupts</code>

會發現是RES(重排程中斷),這個中斷類型表示,喚醒空閑狀态的CPU來排程新的任務運作。

使用工具top和ps:

(1)top:顯示系統總體的CPU和記憶體使用情況,以及各個程序的資源使用情況,預設每隔3秒重新整理一次

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

空白行之後是程序的實時資訊,每個程序都有一個%CPU列,表示程序的CPU使用率。

它是使用者态和核心态CPU使用率總和,包括程序使用者空間使用的CPU、通過系統調用執行的核心空間CPU、以及在就緒隊列等待運作的CPU。在虛拟化環境中,它還包括了運作虛拟機占用的CPU。

Top并沒有細分程序的使用者态CPU和核心态CPU,那麼怎麼檢視每個程序的詳細情況呢:<code>pidstat 1 5</code>(每隔1秒輸出一組資料,共輸出5組 )

(2)ps:隻顯示每個程序的資源使用情況

CPU過高排查工具:想知道占用CPU的到底是代碼裡的哪個函數,找到它,才能更高效、更針對性地進行優化。

(1)<code>GDB(the GNU Project Debugger)</code>功能強大的程式調試利器,但不适合在性能分析的早期應用,因為GDB調試程式過程會中斷程式運作,這線上上環境往往是不允許的。

(2)<code>perf(Linux2.6.31以後内置的性能分析工具)</code>,它以性能事件采樣為基礎,不僅可以分析系統的各種事件和核心性能,還可以用來分析指定應用程式的性能問題。如系統沒有,請安裝:<code>yum install -y perf</code>

perf兩種常見用法:

(1)perf top類似于top,它能夠實時顯示占用CPU時鐘最多的函數或指令,是以可以用來查找熱點函數,如下:

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

第一行包含三個資料,分别是:采樣數(Samples)、事件類型(event)和事件總數量(Event count)

另外注意:如果采樣數過少(比如直有十幾個),那下面的排序和百分比就沒有什麼實際參考價值了。

再往下看是一個表格式樣的資料,每一行包含四列,分别是:

第一列<code>Overhead</code>,是該符号的性能事件在所有采樣中的比例,用百分比來表示。

第二列<code>Shared</code>,是該函數或指令所在的動态共享對象(Dynamic Shared Object),如核心、程序名、動态連結庫名、核心子產品名等。

第三列<code>Object</code>,是動态共享對象的類型。比如[.]表示使用者空間的可執行程式、或者動态連結庫,而[k]則表示核心空間。

第四列<code>Symbol</code>是符号名,也就是函數名。當函數名未知時,用十六進制的位址來表示。

(2)perf record和perf report

<code>perf top</code>雖然實時展示了系統的性能資訊,但它缺點是不能儲存資料,也就是無法用于離線或者後續的分析。

<code>perf record</code>則提供了儲存資料的功能,儲存後的資料,需要用perf report解析展示。

實際工作中,我們還經常為perf top和perf record加上<code>-g</code>參數,開啟調用關系的采樣,友善我們根據調用鍊來分析性能問題。

比如:<code>perf top -g -p 21515</code>(-g開啟調用關系分析,-p指定服務的程序号是21515)

HTTP服務性能測試工具:<code>ab(apache bench)</code>

比如:<code>ab -c 10 -n 1000 http://192.168.246.191:80/</code>(并發10個請求,總共測試1000個請求)

<code>pidstat -p 24344</code>(指定PID是24344的程序)

<code>Pstree</code> 用樹狀形式顯示所有程序之間的關系

<code>grep stress -r app/</code> (<code>-r</code>目錄遞歸)

<code>execsnoop</code> :一個專門為段時程序設計的工具。它通過ftrace實時監控程序的exec()行為,并輸出短時程序的基本資訊,包括程序的PID、父程序PID、指令行參數以及執行的結果。

正常無法解釋的CPU使用率情況,有可能是下面這兩種情況:

(1)應用裡直接調用了其他二進制程式,這些程式通常運作時間比較短,通過top等工具不容易發現;

(2)應用本身在不停地奔潰重新開機,而啟動過程的資源初始化,很可能會占用相當多的CPU;

對于這類程序,我們可以用pstree或者execsnoop找到它們的父程序,再從父程序所在的應用入手,排查問題的根源。

注意⚠️:當碰到無法解釋的CPU使用率問題時,先要檢查下是不是短時應用在搗鬼!

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

程序常見的五種狀态:

(1)<code>R</code> 是 Running 或 Runnable 的縮寫,表示程序在 CPU 的就緒隊列中,正在運作或者正在等待運作。

(2)<code>D</code> 是 Disk Sleep 的縮寫,也就是不可中斷狀态睡眠(Uninterruptible Sleep),一般表示程序正在跟硬體互動,并且互動過程不允許被其他程序或中斷打斷。

注意⚠️:程序長時間處于不可中斷狀态,通常表示系統有 I/O 性能問題。

(3)<code>Z</code> 是 Zombie 的縮寫,如果你玩過“植物大戰僵屍”這款遊戲,應該知道它的意思。它表示僵屍程序,也就是程序實際上已經結束了,但是父程序還沒有回收它的資源(比如程序的描述符、PID 等)。

(4)<code>S</code> 是 Interruptible Sleep 的縮寫,也就是可中斷狀态睡眠,表示程序因為等待某個事件而被系統挂起。當程序等待的事件發生時,它會被喚醒并進入 R 狀态。

(5)<code>I</code> 是 Idle 的縮寫,也就是空閑狀态,用在不可中斷睡眠的核心線程上。前面說了,硬體互動導緻的不可中斷程序用 D 表示,但對某些核心線程來說,它們有可能實際上并沒有任何負載,用 Idle 正是為了區分這種情況。要注意,D 狀态的程序會導緻平均負載升高,I 狀态的程序卻不會。

程序不常見的兩種狀态:

(1)<code>T 或者 t</code>,也就是 Stopped 或 Traced 的縮寫,表示程序處于暫停或者跟蹤狀态。

向一個程序發送 SIGSTOP 信号,它就會因響應這個信号變成暫停狀态(Stopped);再向它發送 SIGCONT 信号,程序又會恢複運作(如果程序是終端裡直接啟動的,則需要你用 fg 指令,恢複到前台運作)。

而當你用調試器(如 gdb)調試一個程序時,在使用斷點中斷程序後,程序就會變成跟蹤狀态,這其實也是一種特殊的暫停狀态,隻不過你可以用調試器來跟蹤并按需要控制程序的運作。

(2)<code>X</code>,也就是 Dead 的縮寫,表示程序已經消亡,是以你不會在top 或者 ps 指令中看到它。

注意⚠️:<code>Ss+</code>:S表示可中斷睡眠狀态,s表示這個程序是一個會話的上司程序,而+表示前台程序組。

程序組與會話:

它們是管理一組互相關聯的程序,意思如下:

(1)程序組表示一組互相關聯的程序,比如每個子程序都是父程序所在組的成員;

(2)會話是指共享同一個控制端的一個或多個程序組;

比如,我們通過 SSH 登入伺服器,就會打開一個控制終端(TTY),這個控制終端就對應一個會話。而我們在終端中運作的指令以及它們的子程序,就構成了一個個的程序組,,其中,在背景運作的指令,構成背景程序組;在前台運作的指令,構成前台程序組。

安裝dstat

(1)<code>CentOS:yum install -y dstat</code>

(2)<code>Ubuntu:apt install dstat</code>

這裡dstat是一個新的性能工具,它吸收了vmstat、iostat、ifstat等幾種工具的優點,可以同時觀察系統的CPU、磁盤I/O、網絡以及記憶體使用情況。

工具使用:

(1)<code>dstat 1 10</code> (間隔1秒輸出10組資料)

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

(2)<code>pidstat -d -p 4344 1 3</code> (-d 展示 I/O 統計資料,-p 指定程序号,間隔 1 秒輸出 3 組資料)

(3)<code>strace -p 6082</code> (-p指定程序号)

Strace最常用的跟蹤程序系統調用的工具。

(4)<code>perf record -g</code>(終端運作十五分鐘左右,再ctrl+c)

(5)<code>perf report</code>

僵屍程序的處理

要解決僵屍程序,就要找到它的根兒,也就是找出父程序,然後在父程序裡解決。

(1)<code>pstree -aps 3084</code>(-a表示輸出指令行選項,p表示PID,s表示指定程序的父程序)

Linux性能優化讀書筆記01檢視系統cpu個數:性能工具的安裝:實戰

運作完,你會發現 3084 号程序的父程序是 4009,也就是 app 應用。

(2)接着檢視 app 應用程式的代碼,看看子程序結束的處理是否正确,比如有沒有調用wait() 或 waitpid() ,抑或是,有沒有注冊 SIGCHLD 信号的處理函數。

繼續閱讀