Linux 通過 /proc 虛擬文件系統,向用戶空間提供了系統內部狀態的信息,而 /proc/stat 提供的就是系統的 CPU 和任務統計信息
proc - process information pseudo-file system
查詢 man proc
關鍵指標常用參數
user(通常縮寫為 us),代表用戶態 CPU 時間。註意,它不包括下面的 nice 時間,但包括了 guest 時間。
nice(通常縮寫為 ni),代表低優先級用戶態 CPU 時間,也就是進程的 nice 值被調整為 1-19 之間時的 CPU 時間。這裏註意,nice 可取值範圍是 -20 到 19,數值越大,優先級反而越低。
system(通常縮寫為 sys),代表內核態 CPU 時間。
idle(通常縮寫為 id),代表空閑時間。註意,它不包括等待 I/O 的時間(iowait)。
iowait(通常縮寫為 wa),代表等待 I/O 的 CPU 時間。
irq(通常縮寫為 hi),代表處理硬中斷的 CPU 時間。
softirq(通常縮寫為 si),代表處理軟中斷的 CPU 時間。
steal(通常縮寫為 st),代表當系統運行在虛擬機中的時候,被其他虛擬機占用的 CPU 時間。
guest(通常縮寫為 guest),代表通過虛擬化運行其他操作系統的時間,也就是運行虛擬機的 CPU 時間。
guest_nice(通常縮寫為 gnice),代表以低優先級運行虛擬機的時間
工具使用
top
[root@k8s ~]# top
top - 15:16:08 up 4 days,? 3:12,? 1 user,? load average: 3.77, 2.88, 2.52
Tasks: 255 total,? 1 running, 254 sleeping,? 0 stopped,? 0 zombie
%Cpu0? : 99.7 us,? 0.3 sy,? 0.0 ni,? 0.0 id,? 0.0 wa,? 0.0 hi,? 0.0 si,? 0.0 st
%Cpu1? : 42.3 us,? 4.8 sy,? 0.0 ni, 50.2 id,? 0.7 wa,? 0.0 hi,? 2.0 si,? 0.0 st
KiB Mem :? 8173864 total,? 753088 free,? 3961556 used,? 3459220 buff/cache
KiB Swap: 0 total, 0 free, 0 used.? 3474088 avail Mem
PID USER ? PR? NI VIRT RES SHR S? %CPU %MEM TIME+ COMMAND
3482 root ? 20? 0 2430460? 1224 760 S? 93.7? 0.0 832:50.08 kswapd0
29995 root ? 20? 0 5279240? 26508? 1760 S? 64.2? 0.3? 25:58.04 tsm
2928 root ? 20? 0 1485424 171912? 36504 S? 6.6? 2.1 317:33.63 kubelet
18035 root ? 20? 0? 164248? 2480? 1612 R? 0.3? 0.0? 0:00.53 top
// top 默認顯示的是所有 CPU 的平均值,這個時候妳只需要按下數字 1 ,就可以切換到每個 CPU 的使用率了。
S 列(也就是 Status 列)表示進程的狀態
進程的狀態主要有以下幾個:
R 是 Running 或 Runnable 的縮寫,表示進程在 CPU 的就緒隊列中,正在運行或者正在等待運行。
D 是 Disk Sleep 的縮寫,也就是不可中斷狀態睡眠(Uninterruptible Sleep),壹般表示進程正在跟硬件交互,並且交互過程不允許被其他進程或中斷打斷。
Z 是 Zombie 的縮寫,它表示僵屍進程,也就是進程實際上已經結束了,但是父進程還沒有回收它的資源(比如進程的描述符、PID 等)。
S 是 Interruptible Sleep 的縮寫,也就是可中斷狀態睡眠,表示進程因為等待某個事件而被系統掛起。當進程等待的事件發生時,它會被喚醒並進入 R 狀態。
I 是 Idle 的縮寫,也就是空閑狀態,用在不可中斷睡眠的內核線程上。前面說了,硬件交互導致的不可中斷進程用 D 表示,但對某些內核線程來說,它們有可能實際上並沒有任何負載,用 Idle 正是為了區分這種情況。要註意,D 狀態的進程會導致平均負載升高, I 狀態的進程卻不會。
pidstat
用戶態 CPU 使用率 (%usr);
內核態 CPU 使用率(%system);
運行虛擬機 CPU 使用率(%guest);
等待 CPU 使用率(%wait);
總的 CPU 使用率(%CPU)。
[root@k8s ~]# pidstat 1 5
Linux 3.10.0-1062.4.1.el7.x86_64 (instance-010oj085) 04/06/2020? _x86_64_ (2 CPU)
03:23:11 PM? UID ? PID %usr %system? %guest %CPU? CPU? Command
03:23:12 PM 0 ? 1403 0.00 0.97 0.00 0.97 1? kube-controller
03:23:12 PM 0 ? 1638 0.97 0.00 0.00 0.97 1? etcd
03:23:12 PM 0 ? 2492 0.00 1.94 0.00 1.94 1? pidstat
03:23:12 PM 0 ? 2574 0.00 0.97 0.00 0.97 1? hosteye
03:23:12 PM 0 ? 2928 1.94 0.97 0.00 2.91 1? kubelet
03:23:12 PM 0 ? 3233 0.97 0.00 0.00 0.97 1? kube-apiserver
03:23:12 PM 0 ? 3482? 100.00 0.00 0.00? 100.00 1? kswapd0
perf
perf 是 Linux 2.6.31 以後內置的性能分析工具。它以性能事件采樣為基礎,不僅可以分析系統的各種事件和內核性能,還可以用來分析指定應用程序的性能問題。可以查找熱點函數。
[root@k8s ~]# perf top
Samples: 75K of event 'cycles', 4000 Hz, Event count (approx.): 26597196684 lost: 0/0 drop: 0/0
Overhead? Shared Object ? Symbol
? 1.57%? kswapd0 [.] 0x00000000001c8641
? 1.10%? perf-3482.map ? [.] 0x00007fdbbf621e8c
? 0.68%? tsm64 ? [.] 0x000000000002f147
? 0.61%? kswapd0 [.] 0x00000000001c8647?
? 0.60%? perf-3482.map ? [.] 0x00007fdbbf621eb5
輸出結果中,第壹行包含三個數據,分別是采樣數(Samples)、事件類型(event)和事件總數量(Event count)。
第壹列 Overhead ,是該符號的性能事件在所有采樣中的比例,用百分比來表示。
第二列 Shared ,是該函數或指令所在的動態***享對象(Dynamic Shared Object),如內核、進程名、動態鏈接庫名、內核模塊名等。
第三列 Object ,是動態***享對象的類型。比如 [.] 表示用戶空間的可執行程序、或者動態鏈接庫,而 [k] 則表示內核空間。
最後壹列 Symbol 是符號名,也就是函數名。當函數名未知時,用十六進制的地址來表示。
dstat
dstat可以讓妳實時地看到所有系統資源,例如,妳能夠通過統計IDE控制器當前狀態來比較磁盤利用率,或者直接通過網絡帶寬數值來比較磁盤的吞吐率(在相同的時間間隔內)
[root@k8s ~]# dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read? writ| recv? send|? in? out | int? csw
67? 3? 29? 0? 0? 1|4910B? 470k|? 0 0 |? 0 0 |3645? 4917
89? 3? 6? 0? 0? 3|? 0? 724k| 394k? 267k|? 0 0 |5252? 4447
90? 4? 5? 0? 0? 2|? 0? 140k| 362k? 230k|? 0 0 |4917? 4281
84? 3? 12? 0? 0? 2|? 0? 4096B| 287k? 196k|? 0 0 |4854? 4481
84? 4? 11? 0? 0? 1|? 0? 216k| 360k? 235k|? 0 0 |5246? 5545
默認輸出信息:
CPU狀態:CPU的使用率。這項報告更有趣的部分是顯示了用戶,系統和空閑部分,這更好地分析了CPU當前的使用狀況。如果妳看到"wait"壹欄中,CPU的狀態是壹個高使用率值,那說明系統存在壹些其它問題。當CPU的狀態處在"waits"時,那是因為它正在等待I/O設備(例如內存,磁盤或者網絡)的響應而且還沒有收到。
磁盤統計:磁盤的讀寫操作,這壹欄顯示磁盤的讀、寫總數。
網絡統計:網絡設備發送和接受的數據,這壹欄顯示的網絡收、發數據總數。
分頁統計:系統的分頁活動。分頁指的是壹種內存管理技術用於查找系統場景,壹個較大的分頁表明系統正在使用大量的交換空間,或者說內存非常分散,大多數情況下妳都希望看到page in(換入)和page out(換出)的值是0 0。
系統統計:這壹項顯示的是中斷(int)和上下文切換(csw)。這項統計僅在有比較基線時才有意義。這壹欄中較高的統計值通常表示大量的進程造成擁塞,需要對CPU進行關註。妳的服務器壹般情況下都會運行運行壹些程序,所以這項總是顯示壹些數值
pstree
// 指定 pid 查找父進程
[root@k8s ~]# pstree -aps 18035
systemd,1 --switched-root --system --deserialize 22
? `-sshd,2504 -D
? `-sshd,16674
? `-bash,16676
? `-top,18035
總結
用戶 CPU 和 Nice CPU 高,說明用戶態進程占用了較多的 CPU,所以應該著重排查進程的性能問題。
系統 CPU 高,說明內核態占用了較多的 CPU,所以應該著重排查內核線程或者系統調用的性能問題。
I/O 等待 CPU 高,說明等待 I/O 的時間比較長,所以應該著重排查系統存儲是不是出現了 I/O 問題。
軟中斷和硬中斷高,說明軟中斷或硬中斷的處理程序占用了較多的 CPU,所以應該著重排查內核中的中斷服務程序。
進程狀態
ps 或者 top ,可以查看進程的狀態,這些狀態包括運行(R)、空閑(I)、不可中斷睡眠(D)、可中斷睡眠(S)、僵屍(Z)以及暫停(T)等。
不可中斷狀態,表示進程正在跟硬件交互,為了保護進程數據和硬件的壹致性,系統不允許其他進程或中斷打斷這個進程。進程長時間處於不可中斷狀態,通常表示系統有 I/O 性能問題。
僵屍進程表示進程已經退出,但它的父進程還沒有回收子進程占用的資源。短暫的僵屍狀態我們通常不必理會,但進程長時間處於僵屍狀態,就應該註意了,可能有應用程序沒有正常處理子進程的退出。
常見問題
CPU使用率很高,通過top等命令找不到相應的進程
應用裏直接調用了其他二進制程序,這些程序通常運行時間比較短,通過 top 等工具也不容易發現。
應用本身在不停地崩潰重啟,而啟動過程的資源初始化,很可能會占用相當多的 CPU。