Linux CPU Spike, 400% CPU 使用率與的排查紀錄

Roga Lin

2026-08-25 17:00:50 +08:00

前言

最近我在一台 Linux Web Server 上看到一個很反常的現象:CPU 使用率原本長期接近閒置,卻突然在最近幾天的同樣時段反覆出現接近 400% 的高負載,而且每次都持續一段時間,這篇文章整理整個排查過程,以及一些經驗分享:

問題現象

平常 CPU 的使用率幾乎接近 0 ,不過這幾天監控圖上看到的 CPU 在特定某些時段的使用率大約是:

Max: 405%, Avg: 25%, Last: 397%

第一個懷疑:cron job

我的 /etc/crontab 裡面最可疑的是:

* * * * * roga task a

這個 task a 是一隻每分鐘執行一次的排程寄信程式,以往信件量都很小,所以很快就執行完畢。

假設是我內部的問題,使得一次執行時間變長,那可能會出現 process overlap 的情況,加上我沒有用 lock 機制,因此可能發生 process overlap,最後大量 process 同時存在。

10:00 task a
10:01 task a
10:02 task a
10:03 task a
10:04 task a
...

先抓即時 process 有哪些

當 CPU 高的時候,可以先看看有哪些 process 正在執行。

ps -eo pid,ppid,user,%cpu,%mem,etime,cmd --sort=-%cpu | head -30

這樣可以看到:

如果問題是上面提到的 cron overlap,很容易看到:

task a
task a
task a
task a
task a
task a

大量重複存在。

不過我實際上機器查問題的時候,並沒有觀察到這個現象。

從監控圖縮小排查範圍

我從 VM 主機商那邊看系統監控圖,把 CPU、Disk I/O、IPv4、IPv6 放在一起比較,最明顯的現象是:

CPU       約下午 4 點開始高負載
CPU       午夜前後恢復正常

Disk I/O  和 CPU 的表現一致

而網路流量並沒有出現同樣形狀的同步暴增。

因此可以合理地把網路因素的可能性往後排,我自己推測應該是:

本機 batch / DB / filesystem 工作
        ↓
CPU 大量運算
        +
Disk I/O 大量活動
        ↓
持續數小時
        ↓
工作完成後同時恢復正常

可能的方向包括:

異常發生時要怎麼找出 root cause

老實說,這類問題最大的麻煩是發生狀況的當下,我有很大機率都不在線上,所以我弄了一個監控的 cpu-watch.sh ,功能如下:

以下是 cpu-watch.sh 最後的版本:

https://github.com/roga/cpu-watch

這隻 script 在每個 INTERVAL 週期都會獨立量測下列指標:

只要任一已設定的條件連續 TRIGGER_COUNT 次量測成立,就會開始一個 incident。這個設計可以避免短暫雜訊造成誤判;預設連續兩次(約 10 秒)比原本固定等待 15 秒、只看 CPU 的作法更快回應。因此,即使 BUSY_CPU 不高,純 I/O 異常也可能建立 incident log。

平常量測時只會讀:

/proc/stat
/proc/diskstats

基本上不會造成明顯 disk I/O。

Incident log 的內容

這隻 script 在偵測到異常時會在 /var/log/cpu-watch/ 底下建立 log file 。

例如:

incident-20260825-162315.log
incident-20260826-160842.log
incident-20260827-161102.log

用日期時間設計的好處是只要看檔名就能知道 CPU 異常是不是每天都在同一個時間出現,也方便然直接進去特定的 log 檔抓問題。

同時紀錄 vmstat

然而 CPU 使用率高,不代表一定是 CPU 在拼命計算,加上 vmstat 的紀錄也可以區分到底是卡在哪

us = user CPU
sy = system CPU
wa = I/O wait
id = idle

舉例一:(CPU 真的在運算)

us sy wa id
85 10  1  4

舉例二:(在等 storage I/O)

us sy wa id
10  5 80  5

查看結果

之後再根據時間點,找查 log ,這樣就更容易找出 root cause:

less /var/log/cpu-watch/incident-20260825-162315.log

這次排查的核心思路

對偶發性的 server CPU spike 來說,這種「事件導向蒐證」會比一直寫大量監控 log 更有效率,只要設好臨界點,等條件觸發再寫紀錄就好了。