Linux 維運實戰排錯與疑難雜症手冊
引言:維運排錯的系統性心智模型
在 Linux 與 macOS 的日常維運中,我們總會遇到一些讓人措手不及的「靈異現象」:
- 磁碟明明顯示還有幾十 GB 空間,寫入檔案卻提示
No space left on device; - 服務連接埠被佔用,卻查不到任何監聽行程;
- 容器或後端服務莫名其妙被系統靜默殺死,沒有任何業務日誌;
- 高併發場景下突然爆發大量
Too many open files導致雪崩。
排錯不僅是敲幾條指令,更是順藤摸瓜的系統性推導過程。本文匯集一線維運中最高頻的 6 類疑難雜症,給出可直接落地的排查邏輯與根治方案。
flowchart TD
Issue["系統異常與服務警報"] --> A["1. 檔案句柄耗盡<br/>(Too Many Open Files)"]
Issue --> B["2. 磁碟爆滿/假滿<br/>(Inode 耗盡 / 句柄未釋放)"]
Issue --> C["3. 連接埠衝突與殭屍行程<br/>(Address in use / Zombie)"]
Issue --> D["4. 記憶體溢出被殺<br/>(Kernel OOM Killer)"]
Issue --> E["5. 時鐘偏差與鑑權失效<br/>(Clock Skew / NTP 同步)"]
Issue --> F["6. macOS 環境網路阻塞<br/>(Homebrew 源與網路排查)"]
一、 徹底解決 Too Many Open Files(檔案句柄耗盡)
在 Linux 與 macOS 哲學中,「一切皆檔案」。當併發連線數或開啟的檔案數超過系統預設限制時,就會拋出 Too many open files 錯誤。
1. Linux 生產環境徹底調優
① 修改系統級限制 (/etc/security/limits.conf)
1* soft nofile 655350
2* hard nofile 655350
3root soft nofile 655350
4root hard nofile 655350
② 修改 systemd 全域服務限制 (/etc/systemd/system.conf)
1[Manager]
2DefaultLimitNOFILE=655350
3DefaultLimitNPROC=655350
③ 查看當前行程佔用的句柄數
1ls /proc/<PID>/fd | wc -l
2. macOS 開發者環境調優
1# 查看當前限制
2launchctl limit maxfiles
3
4# 臨時增加限制 (當前終端機有效)
5sudo launchctl limit maxfiles 65536 200000
6ulimit -n 65536
二、 磁碟「假滿」與 Inode 耗盡 (No space left on device)
sequenceDiagram
autonumber
participant App as 應用程式 (如 Nginx / Java)
participant Disk as 磁碟檔案 (/var/log/app.log)
participant Admin as 維運工程師
App->>Disk: 持續寫入大量日誌 (持有檔案句柄)
Admin->>Disk: rm /var/log/app.log (刪除了檔名)
Note over Disk: 空間無法釋放!因為 App 仍持有該句柄
Admin->>App: 尋找未釋放句柄 (lsof | grep deleted) 並平滑重載
Note over Disk: 磁碟空間瞬間恢復!
場景 A:檔案已被 rm 刪除,但行程仍持有句柄未釋放
1# 1. 尋找所有已被刪除但仍被行程佔用的檔案
2sudo lsof | grep -i deleted
3
4# 2. 優雅釋放空間(清空該行程對應的檔案描述符):
5sudo truncate -s 0 /proc/<PID>/fd/<FD>
6# 或平滑重載服務:sudo systemctl reload nginx
場景 B:磁碟空間充足,但 Inode(索引節點)耗盡
1# 1. 檢查 Inode 佔用率
2df -i
3
4# 2. 逐級統計哪個目錄下的小檔案最多
5find /var/spool/ -type d -exec sh -c "echo -n '{}: '; ls -1 '{}' | wc -l" \; | sort -n -k 2
三、 連接埠佔用衝突與殭屍行程清理
1. 連接埠佔用排查與一秒殺死
1# 1. 精準定位佔用 8080 連接埠的行程與 PID
2sudo lsof -i :8080
3# 或
4sudo ss -tulnp | grep :8080
5
6# 2. 強力一鍵釋放連接埠(自動殺死佔用者)
7sudo fuser -k 8080/tcp
2. 殭屍行程(Zombie Process)定位與清理
1# 1. 查看系統中的所有殭屍行程 (狀態為 Z)
2ps aux | grep 'Z'
3
4# 2. 尋找殭屍行程的父行程 PID (PPID)
5ps -o ppid= -p <ZOMBIE_PID>
6
7# 3. 優雅重啟或終止父行程,讓 init/systemd 回收殭屍
8sudo kill -HUP <PARENT_PID>
四、 行程靜默被殺:Linux 核心 OOM Killer 排查
1# 1. 檢查核心是否有 OOM 擊殺紀錄
2sudo dmesg -T | grep -i -E "oom|out of memory|killed process"
根治策略:
- 新增 Swap 交換分區:
1sudo fallocate -l 2G /swapfile 2sudo chmod 600 /swapfile 3sudo mkswap /swapfile 4sudo swapon /swapfile 5echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab - 在 Docker / Kubernetes 中設定合理的記憶體 Limit。
五、 系統時鐘不同步導致 TLS/SSL 憑證與鑑權失效
1# 1. 檢查當前系統時間與 NTP 同步狀態
2timedatectl status
3
4# 2. 設定時區並開啟 NTP 自動同步
5sudo timedatectl set-timezone Asia/Taipei
6sudo timedatectl set-ntp true
六、 macOS 開發環境 Homebrew 映像加速與復原
1# 1. 切換為開源映像源
2export HOMEBREW_API_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles/api"
3export HOMEBREW_BOTTLE_DOMAIN="https://mirrors.tuna.tsinghua.edu.cn/homebrew-bottles"
4export HOMEBREW_BREW_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/brew.git"
5export HOMEBREW_CORE_GIT_REMOTE="https://mirrors.tuna.tsinghua.edu.cn/git/homebrew/homebrew-core.git"
6
7# 2. 恢復為官方預設源
8unset HOMEBREW_API_DOMAIN
9unset HOMEBREW_BOTTLE_DOMAIN
10export HOMEBREW_BREW_GIT_REMOTE="https://github.com/Homebrew/brew"
11export HOMEBREW_CORE_GIT_REMOTE="https://github.com/Homebrew/homebrew-core"
12brew update