阿克森雲登入 / 註冊English/中文/cn繁體/tw

第 3 課 · 進程與資源:top/ps/kill,看誰在喫內存

Linux 基礎 · L1 · 第 3 / 6 節 · 約 3 分鍾

服務器變慢的第一排查動作不是重啓,是看清楚誰在喫資源。這一課教會你用 top、ps、free、df 四件工具回答四個問題:CPU 被誰佔了、內存還剩多少、磁盤滿沒滿、怎麼安全地終止失控進程。

資源排查四問示意

進程是什麼:PID 與父子關系

運行中的程序就是進程,每個進程有唯一編號 PID;進程可以派生子進程(Nginx 主進程帶一堆 worker 就是典型)。PID 1 是所有進程的祖先(現代系統上是 systemd)。查進程樹:

ps auxf | less        # 全量進程帶樹形縮進(f 參數畫出父子關系)
pstree -p | head -30  # 更直觀的進程樹
pgrep -a nginx        # 按名字找 PID(-a 帶命令行)

top:實時儀表盤怎麼讀

top        # 進入實時視圖;q 退出
# 常用交互鍵:P 按CPU排序 · M 按內存排序 · k 輸入PID發信號 · 1 展開每核

頭部三行的讀法:load average(1/5/15 分鍾平均負載——與核數比:4 核機器 load 4 以下算健康,持續超過核數就是排隊);%Cpu 行的 us(用戶程序)/sy(內核)/wa(等 IO——wa 高說明磁盤是瓶頸不是 CPU)/id(空閒);MiB Mem 行的 free 與 available——看 available 不看 free:Linux 會把空閒內存拿去做磁盤緩存(buff/cache),需要時立刻還給程序,available 才是真實餘量。

ps 與精確過濾

ps aux --sort=-%mem | head -8    # 內存大戶前 8 名
ps aux --sort=-%cpu | head -8    # CPU 大戶前 8 名
ps -o pid,ppid,user,%cpu,%mem,etime,cmd -p 某個PID   # 單進程詳情(含運行時長)

free / df / du:內存與磁盤的兩本賬

free -h                # 內存:重點看 available 列與 Swap 使用
df -h                  # 各掛載點的磁盤餘量(Use% 到 90% 就該處理)
du -sh /var/log/* | sort -rh | head    # 誰在喫磁盤:日志目錄常是第一名
du -xh / --max-depth=2 2>/dev/null | sort -rh | head   # 全盤大戶掃描(-x 不跨文件系統)

磁盤滿的連鎖反應比內存滿更兇險:日志寫不進、數據庫拒絕寫、SSH 登入都可能失敗——df 看到 90%+ 立即找大戶(通常是日志與緩存),清完再想擴容。

kill:終止進程的信號分級

kill 12345        # 發 SIGTERM(15):請進程自己收尾退出——永遠先試這個
kill -9 12345     # 發 SIGKILL(9):內核直接抹掉——數據可能損壞,最後手段
kill -HUP 12345   # 發 SIGHUP(1):多數守護進程的解釋是「重讀配置」
pkill -f 關鍵詞    # 按命令行關鍵詞終止(小心匹配面,先 pgrep -f 預覽)

紀律:TERM 等十秒,不走再 KILL——數據庫與帶緩存的服務被 -9 直接抹掉,輕則丟緩存重則壞數據文件。終止系統關鍵進程(systemd 管理的服務)的正確姿勢是 systemctl stop 服務名,讓管理器知道狀態。

綜合排查:一次「機器卡」的完整流程

# ① 負載與 CPU:load 是否超核數、wa 是否高
top -bn1 | head -5
# ② 內存:available 還剩多少、Swap 是否在猛用
free -h
# ③ 磁盤:餘量與 IO 大戶
df -h / && du -sh /var/log /tmp 2>/dev/null
# ④ 找出大戶並處置(先確認它是什麼再動手)
ps aux --sort=-%mem | head -5
# ⑤ 處置後復測①②③——數字回落才算解決;反復出現則查它爲什麼失控

IO 等待:第三種瓶頸的識別

CPU 高與內存滿之外,第三種「機器卡」的元兇是磁盤 IO 瓶頸,特徵是 top 裏 wa(iowait)佔比高而 us/sy 不高——CPU 在空等磁盤。確認與定位兩步:iostat -x 1 5(sysstat 包)看每塊盤的 %util(接近 100% 即飽和)與 await(平均 IO 等待毫秒數,機械盤幾十毫秒正常、固態盤超過個位數就該注意);iotop(需要裝)直接列出誰在讀寫。典型場景:日志瘋狂刷盤(應用報錯循環)、備份任務撞上了業務高峯、機械盤跑數據庫。處置口徑:先停掉可停的(備份挪窗口)、再治本(報錯循環修應用、數據庫遷固態)——「重啓解決」在 IO 瓶頸上通常只是清空了隊列,十分鍾後原樣復發。

長期觀察:給自己建一條監控基線

排查工具都是「現場看」,而多數性能問題有前兆——磁盤以每天 1% 的速度爬向 100%、內存佔用周級緩漲(泄漏的典型曲線)。不裝監控系統的最小方案是一條 crontab:*/10 * * * * echo "$(date +\%F\ \%H:\%M) $(df -h / | awk 'NR==2{print $5}') $(free -m | awk '/Mem/{print $3}') $(uptime | grep -o 'load average.*')" >> /var/log/baseline.log——每 10 分鍾記一行「時間 磁盤% 內存MB 負載」,一個月後 tail -100 或丟進表格畫圖,趨勢一目了然。有監控需求的下一步是 Prometheus 類系統,但在第一臺服務器上,這條 cron 就是性價比最高的「監控」。

本節小結

  • 負載看 load 與核數的比值、內存看 available 不看 free、磁盤看 df 的 Use%;
  • kill 分級:TERM 請退、KILL 強殺,中間隔十秒;託管服務用 systemctl;
  • 「機器卡」的排查是固定五步:負載→內存→磁盤→大戶→復測,每步都有命令。