Linux 性能監控與故障排查:主要性能指標說明及監控方法


一台 Linux 服務器的四類指標如下:

  1. CPU:使用率、平均負載(load average)
  2. RAM:used | free | buffer/cache | avaliable
  3. Disk:空閑容量大小、IO 狀態
  4. Network:網速、延遲、丟包率等

下面詳細地說明各項系統參數的意義、它們的正常狀態,以及出現異常時如何進行故障排查。

零、前置准備

很多的監控工具 Ubuntu/CentOS 都不自帶,需要手動安裝,在開始前我們最好先把所有可能用得上的監控工具都裝上。(它們都很小,基本不占空間)

# ubuntu/debian
sudo apt-get install \
    sysstat iotop fio \
    nethogs iftop

# centos
# 需要安裝 epel 源,很多監控工具都在該源中!
# 也可使用[阿里雲 epel 源](https://developer.aliyun.com/mirror/epel)
sudo yum install epel-release
sudo yum install \
    sysstat iotop fio \
    nethogs iftop

大一統的監控工具

下面介紹兩個非常方便的大一統監控工具,它們將一台服務器的所有監控數據匯總到一個地方,方便監控。

多機監控推薦用 prometheus+grafana,不過這一套比較吃性能,個人服務器沒必要上。

NetData: 極簡安裝、超詳細超漂亮的 Web UI

這里只介紹單機監控。NetData 也支持中心化的多機監控,待進一步研究。netdata 也可以被用作 prometheus 的 exporter.

NetData 我要吹爆!它是 Github 上最受歡迎的系統監控工具,目前已經 44.5k star 了。
CPU 占用率低(0.1 核),界面超級漂亮超級詳細,還對各種指標做了很詳細的說明,安裝也是一行命令搞定。相當適合萌新運維。

默認通過 19999 端口提供 Web UI 界面。

sudo apt-get install netdata
# 然后修改 /etc/netdata/netdata.conf,綁定 ip 設為 0.0.0.0
sudo systemctl restart netdata

現在就可以訪問 http://<server-ip>:19999 查看超級漂亮超級詳細的監控界面了!

Glances: 同樣極簡安裝、方便的命令行 UI

netdata 只以 Web 服務器的方式提供 Web UI,因此必須常駐后台。
如果只是想要臨時在 ssh 控制台進行監控,可以使用 Glances,安裝命令如下:

sudo apt-get install glances

sudo yum install glances

啟動命令:glances,可提供 CPU、RAM、NetWork、Disk 和系統狀態等非常全面的信息。(只是不夠詳細)

glances 同樣提供中心化的多機監控,還有 Web 界面,但是和 netdata 相比就有些簡陋了。不作介紹。

一、CPU 指標

1. CPU 使用率

CPU 使用率即 CPU 運行在非空閑狀態的時間占比,它反應了 CPU 的繁忙程度。使用 top 命令我們可以得到如下信息:

%Cpu(s):  0.0 us,  2.3 sy,  0.0 ni, 97.7 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
  • us(user):表示 CPU 在用戶態運行的時間百分比,通常用戶態 CPU 高表示有應用程序比較繁忙。典型的用戶態程序包括:數據庫、Web 服務器等。
  • sy(sys):表示 CPU 在內核態運行的時間百分比(不包括中斷),通常內核態 CPU 越低越好,否則表示系統存在某些瓶頸。
  • ni(nice):表示用 nice 修正進程優先級的用戶態進程執行的 CPU 時間。nice 是一個進程優先級的修正值,如果進程通過它修改了優先級,則會單獨統計 CPU 開銷。
  • id(idle):表示 CPU 處於空閑態的時間占比,此時,CPU 會執行一個特定的虛擬進程,名為 System Idle Process。
  • wa(iowait):表示 CPU 在等待 I/O 操作完成的時間占比,通常該指標越低越好,否則表示 I/O 可能存在瓶頸,需要用 iostat 等命令做進一步分析。
    • iowait 只考慮 Synchronous File IO,It does NOT count time spent waiting for IPC objects such as sockets, pipes, ttys, select(), poll(), sleep(), pause() etc.
  • hi(hardirq):表示 CPU 處理硬中斷所花費的時間。硬中斷是由外設硬件(如鍵盤控制器、硬件傳感器等)發出的,需要有中斷控制器參與,特點是快速執行。
  • si(softirq):表示 CPU 處理軟中斷所花費的時間。軟中斷是由軟件程序(如網絡收發、定時調度等)發出的中斷信號,特點是延遲執行。
  • st(steal):表示 CPU 被其他虛擬機占用的時間,僅出現在多虛擬機場景。如果該指標過高,可以檢查下宿主機或其他虛擬機是否異常。

2. 平均負載(Load Average)

top 命令的第一行輸出如下:

top - 21:11:00 up 8 min,  0 users,  load average: 0.52, 0.58, 0.59

其中帶有三個平均負載的值,它們的意思分別是** 1 分鍾(load1)、5 分鍾(load5)、15 分鍾(load15)內系統的平均負載**。

平均負載(Load Average)是指單位時間內,系統處於 可運行狀態(Running / Runnable)不可中斷態 的平均進程數,也就是 平均活躍進程數。

我們知道實際上一個 CPU 核只能跑一個進程,操作系統通過分時調度提供了多進程並行的假象。所以當平均負載(平均活躍進程數)不大於 CPU 邏輯核數時,系統可以正常運轉。
如果平均負載超過了核數,那就說明有一部分進程正在活躍中,但是它卻沒有使用到 CPU(同一時間只能有 1 個進程在使用 CPU),這只可能有兩個原因:

  1. 這部分進程在排隊等待 CPU 空閑。
  2. 這部分 CPU 在進行 IO 操作。

不論是何種狀況,都說明系統的負載過高了,需要考慮降負或者升級硬件。

理想狀態下,系統滿負荷工作,此時平均負載 = CPU 邏輯核數(4核8線程 CPU 有8個邏輯核)。但是,在實際生產系統中,不建議系統滿負荷運行。通用的經驗法則是:平均負載 <= 0.7 * CPU 邏輯核數

  • 當平均負載持續大於 0.7 * CPU 邏輯核數,就需要開始調查原因,防止系統惡化;
  • 當平均負載持續大於 1.0 * CPU 邏輯核數,必須尋找解決辦法,降低平均負載;
  • 當平均負載持續大於 5.0 * CPU 邏輯核數,表明系統已出現嚴重問題,長時間未響應,或者接近死機。

除了關注平均負載值本身,我們也應關注平均負載的變化趨勢,這包含兩層含義。一是 load1、load5、load15 之間的變化趨勢;二是歷史的變化趨勢。

  • 當 load1、load5、load15 三個值非常接近,表明短期內系統負載比較平穩。此時,應該將其與昨天或上周同時段的歷史負載進行比對,觀察是否有顯著上升。
  • 當 load1 遠小於 load5 或 load15 時,表明系統最近 1 分鍾的負載在降低,而過去 5 分鍾或 15 分鍾的平均負載卻很高。
  • 當 load1 遠大於 load5 或 load15 時,表明系統負載在急劇升高,如果不是臨時性抖動,而是持續升高,特別是當 load5 都已超過 0.7 * CPU 邏輯核數 時,應調查原因,降低系統負載。

日常運維時,應該重點關注上述三個負載值之間的關系。

3. CPU 使用率與平均負載的關系

CPU 使用率是單位時間內 CPU 繁忙程度的統計。而平均負載不僅包括正在使用 CPU 的進程,還包括等待 CPU 或 I/O 的進程(前面講過平均負載過高的兩種情況)。

因此 CPU 使用率是包含在平均負載內的。這兩個參數有兩種組合需要注意:

  1. 兩個參數值都很高:需要降低 CPU 使用率!
  2. CPU 使用率很低,可平均負載卻超過了CPU邏輯核數:IO 有瓶頸了!需要排查 內存/磁盤/網絡 的問題。
    1. 最常遇到的場景:內存用盡導致負載飆升

二、RAM 內存指標

free # 單位 kb
free -m  # 單位 mb
free -g  # 單位 gb

不考慮 Swap 時,建議以 Avaliable 值為可用內存的參考,因為 buffer/cache 中的內存不一定能完全釋放出來!因為:

  1. OS 本身需要占用一定 buffer/cache
  2. 通過 tmpfs 等方式被使用的 cache 不能被回收使用
  3. 通過 cgroups 設置的資源預留無法被別的進程回收利用。(容器資源預留)

內存泄漏

內存泄漏有多種可能,通過監控能確定的只有內存是否在無上限地上升。很難直接通過監控排查。

三、Disk 磁盤指標

Disk 的性能指標主要有:

  1. bandwidth 帶寬,即每秒的 IO 吞吐量
    • 連續讀寫頻繁的應用(傳輸大量連續的數據)重點關注吞吐量,如讀寫視頻的應用。
  2. IOPS,每秒的 IO 次數
    • 隨機讀寫頻繁的應用需要關注 IOPS,如大量小文件(圖片等)的讀寫。

我們是 Web 服務器/數據庫服務器,主要是隨機讀寫,更關注 IOPS。

0. IO 基准測試

要監控磁盤的指標,首先得有個基准值做參考。

方法一:對整塊磁盤進行測試

首先安裝磁盤測試工具 fio(安裝命令見文章開始),然后將如下內容保存為 fio-rand-rw.fio(Web 服務器/數據庫更關注隨機讀寫):

; https://github.com/axboe/fio/blob/master/examples/fio-rand-RW.fio

; fio-rand-RW.job for fiotest

[global]
name=fio-rand-RW
filename=fio-rand-RW
rw=randrw
rwmixread=60
rwmixwrite=40
bs=4K
direct=0
numjobs=4
time_based=1
runtime=900

[file1]
size=4G
ioengine=libaio
iodepth=16

現在運行命令 fio fio-rand-rw.fio 以啟動測試,可根據情況調整 .fio 文件中的參數,最后記錄測試結果。

方法二:使用 dd 進行磁盤速度測試

使用 dd 測試的好處是系統自帶,而且也不會破壞磁盤內容。

# 寫入測試,讀取 /dev/zero 這個空字符流,寫入到 test.dbf 中(就是只測寫入)
# 塊大小為 8k,也就是說偏向隨機寫
dd if=/dev/zero of=test.dbf bs=8k count=50000  oflag=dsync  # 每次寫完一個 block 都同步,傷硬盤,不要沒事就測

# 讀取 /dev/sda1 中的數據,寫入到 /dev/null 這個黑洞中(只測讀取)
# 塊大小還是 8k,即偏向隨機讀
dd if=/dev/sda1 of=/dev/null bs=8k

日常監控的數值遠低於上面測得的基准值的情況下,基本就可以確定磁盤沒有問題。

1. 使用率

通過 df -h 查看磁盤的使用情況,詳細排查流程參見 linux 磁盤占用的排查流程

磁盤不足會導致各種問題,比如:

  1. ElasticSearch 自動將索引設為只讀,禁止寫入。
  2. k8s 報告 "Disk Pressure",導致節點無法調度。
  3. shell 的 tab 補全無法使用,會報錯。

2. IO 帶寬(吞吐量)以及 IOPS

使用 iostat 查看磁盤 io 的狀態(需要安裝 sysstat,安裝命令見文章開頭):

# 每個磁盤一列,給出所有磁盤的當前狀態
iostat -d -k 3  # 以 kb 為單位,3 秒刷新一次
iostat -d -m 3  # 以 mb 為單位,其他不變

# 每個進程一列,可用於排查各進程的磁盤使用狀態
iotop

將監控值與前述測試得到的基准值進行對比,低很多的話,基本就可以確認磁盤沒問題。

四、Network 網絡指標

和 IO 指標類似,網絡指標主要有:

  1. socket 連接
    • 連接數存在上限,該上限與 Linux 的文件描述符上限等參數有關。
    • 廣為人知的 DDOS 攻擊,通過 TCP 連接的 ACK 洪泛來使服務器癱瘓,針對的就是 TCP 協議的一個弱點。
  2. 網絡帶寬(吞吐量)
  3. PPS(Packets Per Second) 數據包的收發速率
  4. 網絡延遲:一般通過 ping 來確定網絡延遲和丟包率
  5. 丟包率等等
  6. DNS 解析

客戶端與服務器之間的整條網絡鏈路的任何一部分出現故障或配置不當,都可能導致上述的監控參數異常,應用無法正常運行。典型的如交換機、負載均衡器、Kubernetes 配置、Linux 系統參數(sysctl/ulimit)配置不當等。

1. 網絡帶寬監控

  1. nethogs: 每個進程的帶寬監控,並且進程是按帶寬排序的
    • 使用:sudo nethogs
    • 快速分析出占用大量帶寬的進程
  2. tcpdump/tshark/mitmproxy: 命令行的網絡抓包工具,mitmproxy 提供 Web UI 界面,而 tshark 是 wireshark 的命令行版本。
    • tcpdump -i eth0 -w dump.pcap: 使用 tcpdump 抓 eth0 的數據包,保存到 dump.pcap 中。之后可以通過 scp/ssh 等命令將該 pcap 文件拷貝下來,使用 wireshark 進行分析。

2. Socket

Socket 的狀態查看方法,參見 Socket 狀態變遷圖及命令行查看方法

# 查看 socket 連接的統計信息
# 主要統計處於各種狀態的 tcp sockets 數量,以及其他 sockets 的統計信息
ss --summary
ss -s  # 縮寫

# 查看哪個進程在監聽 80 端口
# --listening 列出所有正在被監聽的 socket
# --processes 顯示出每個 socket 對應的 process 名稱和 pid
# --numeric 直接打印數字端口號(不解析協議名稱)
ss --listening --processes --numeric | grep 80
ss -nlp | grep 80  # 縮寫
ss -lp | grep http  # 解析協議名稱,然后通過協議名搜索監聽

## 使用過時的 netstat
### -t tcp
### -u udp
netstat -tunlp | grep ":80"

# 查看 sshd 當前使用的端口號
ss --listening --processes | grep sshd
## 使用過時的 netstat
netstat -tunlp | grep <pid>  # pid 通過 ps 命令獲得

# 列出所有的 tcp sockets,包括所有的 socket 狀態
ss --tcp --all

# 只列出正在 listen 的 socket
ss --listening

# 列出所有 ESTABLISHED 的 socket(默認行為)
ss

# 統計 TCP 連接數
ss | grep ESTAB | wc -l

# 列出所有 ESTABLISHED 的 socket,並且給出連接的計時器
ss --options

# 查看所有來自 192.168.5 的 sockets
ss dst 192.168.1.5

# 查看本機與服務器 192.168.1.100 建立的 sockets
ss src 192.168.1.5

# 查看路由表
routel

3. 網絡延遲、丟包率

通過 ping 命令進行測試,使用 pathping (僅 Windows)進行分段網絡延遲與丟包率測試。

4. DNS 故障排查

參見 Linux網絡學習筆記(三):域名解析(DNS)——以 CoreDNS 為例

五、Kubernetes 預留資源

Kubernetes 是通過 Linux 的 cgroups 機制實現的資源預留。

這部分被預留的內存等資源,在 OS 的監控中仍然會是空閑狀態,即使是通過 kubectl top 也是監控不到這部分預留資源的。
因為這部分資源實際上並未被使用,只是在 k8s 中的一個資源限制而已,預留資源目前是一種隱形的資源限制,無法通過系統監控來查看

六、問題排查案例

如果服務器出現問題,但是上述四項參數都沒有明顯異常,就要考慮是不是系統配置或者應用配置的問題了。

1. 僵屍進程

僵屍進程過多,可以在上述指標都非常正常的情況下,使系統響應變得特別慢。
如果通過 top 命令觀察到存在僵屍進程,可以使用如下命令將僵屍進程查找出來:

ps -ef| grep defunc

案例:「Bug」Jenkins Slave 卡頓與僵屍進程

2. sysctl/ulimit 參數設置

sysctl/ulimit 設置不當,可以在上述指標都非常正常的情況下,使系統響應變得特別慢。

案例:為了方便,我在系統的初始化腳本 configure_server.py 里一次性將 redis/elasticsearch/網絡 等 sysctl/ulimit 參數全部配置好。結果 elasticsearch 需要設置的 vm.max_map_count 參數導致 redis 服務器在長時間運行后響應變慢。

七、其他可能用到的命令

  1. ps -ef | more: 查看所有進程的資源使用率(CPU/RAM),以及完整的運行命令。

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM