器CPU占用過高排查與優(yōu)化實戰(zhàn)指南)
1. Linux服務(wù)器CPU占用過高排查指南作為一名運維老兵我處理過的服務(wù)器CPU爆滿問題不下百次。每次半夜被報警短信吵醒看著監(jiān)控圖上那條直沖100%的紅線都得迅速定位問題根源。本文將分享我多年實戰(zhàn)中總結(jié)的CPU問題排查方法論從快速止血到深度分析手把手帶你掌握這套望聞問切的排查流程。2. 核心排查思路與工具選型2.1 診斷工具全景圖Linux系統(tǒng)自帶的性能分析工具鏈堪稱運維人員的瑞士軍刀。根據(jù)問題場景不同我會分層使用這些工具全局監(jiān)控層top/htop實時、vmstat系統(tǒng)級、dstat增強版進程分析層pidstat細粒度、ps aux --sort-%cpu排序線程級分析top -H -p 、pstree -p調(diào)用鏈追蹤strace系統(tǒng)調(diào)用、perf性能熱點高級診斷sar歷史數(shù)據(jù)、bpftrace內(nèi)核級經(jīng)驗安裝sysstat包后使用pidstat 1比單純用top更能看清瞬時CPU波動2.2 快速定位問題方向通過幾個關(guān)鍵指標(biāo)可以快速判斷問題類型CPU負載與使用率關(guān)系load average CPU核心數(shù)且%us高 → 應(yīng)用層問題%sy過高 → 內(nèi)核或系統(tǒng)調(diào)用頻繁%wa高 → I/O等待導(dǎo)致CPU閑置用戶態(tài)/內(nèi)核態(tài)占比# 查看CPU模式分布 mpstat -P ALL 1輸出示例08:30:01 AM CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle 08:30:02 AM all 85.23 0.00 12.31 0.25 0.00 0.21 0.00 0.00 0.00 2.00典型問題特征速查表現(xiàn)象組合可能原因下一步動作%us高 load高業(yè)務(wù)代碼問題分析Java/Python進程%sy高 上下文切換頻繁鎖競爭/進程調(diào)度檢查mutex和線程數(shù)%wa高 iowait高磁盤IO瓶頸檢查await和%util軟中斷高網(wǎng)絡(luò)包處理檢查網(wǎng)絡(luò)流量和網(wǎng)卡隊列3. 詳細排查實戰(zhàn)流程3.1 第一響應(yīng)快速止血當(dāng)CPU持續(xù)滿載時首先要防止系統(tǒng)雪崩隔離問題節(jié)點如果是集群# 從負載均衡池摘除節(jié)點 echo 0 /proc/sys/net/ipv4/ip_forward限制異常進程# 臨時限制CPU使用 cpulimit -l 50 -p PID # 或使用cgroups cgcreate -g cpu:/limit_group echo 100000 /cpu/limit_group/cpu.cfs_quota_us echo PID /cpu/limit_group/tasks保留現(xiàn)場證據(jù)# 抓取進程快照 ps auxf /tmp/ps_$(date %s).log # 保存JVM線程棧如果是Java應(yīng)用 jstack PID /tmp/jstack_$(date %s).log3.2 深度分析五步定位法步驟1定位問題進程# 按CPU排序顯示進程 top -c -o %CPU # 或使用更直觀的htop F6 - PERCENT_CPU - 回車步驟2分析進程內(nèi)部# 查看進程的線程CPU占用 top -H -p PID # 統(tǒng)計系統(tǒng)調(diào)用 strace -cp PID # 采樣調(diào)用棧30秒 perf record -F 99 -p PID -g -- sleep 30 perf report步驟3檢查關(guān)聯(lián)資源# 查看文件打開數(shù) ls -l /proc/PID/fd | wc -l # 檢查內(nèi)存使用 pmap -x PID # 網(wǎng)絡(luò)連接統(tǒng)計 ss -tunap | grep PID步驟4驗證配置參數(shù)# 檢查進程限制 cat /proc/PID/limits # 查看內(nèi)核參數(shù) sysctl -a | grep sched\|timer步驟5歷史對比分析# 查看sar歷史數(shù)據(jù) sar -u -f /var/log/sa/sa$(date %d -d yesterday) # 對比正常時段的CPU使用模式4. 典型場景案例庫4.1 Java應(yīng)用CPU飆升特征%us高大量RUNNABLE線程可能存在鎖競爭排查步驟獲取線程棧jstack PID jstack.log轉(zhuǎn)換線程IDprintf %x\n 十進制線程ID分析熱點代碼# 采樣Java方法調(diào)用 perf record -e cpu-clock -g -p PID perf report常見原因死循環(huán)如while(true)空轉(zhuǎn)鎖競爭查看BLOCKED狀態(tài)線程頻繁GC配合jstat -gcutil分析4.2 內(nèi)核態(tài)CPU占用高特征%sy 30%上下文切換頻繁cs/sec高排查命令# 查看系統(tǒng)調(diào)用統(tǒng)計 perf top -e raw_syscalls:sys_enter # 檢查軟中斷 watch -d -n 1 cat /proc/softirqs解決方案調(diào)整內(nèi)核參數(shù)echo net.ipv4.tcp_max_tw_buckets20000 /etc/sysctl.conf sysctl -p優(yōu)化進程調(diào)度chrt -f -p 99 PID4.3 定時任務(wù)風(fēng)暴現(xiàn)象CPU使用率周期性飆升存在大量sh或cron進程定位方法# 查看最近執(zhí)行的命令 grep CRON /var/log/cron | tail -20 # 檢查anacron任務(wù) ls -l /etc/cron.*/處理方案# 臨時禁用cron systemctl stop crond # 調(diào)整任務(wù)時間分布 for i in {0..59}; do echo $i * * * * sleep $(($RANDOM % 30)); /path/to/job /etc/crontab done5. 高級診斷技巧5.1 使用BPF深度分析# 跟蹤CPU使用最高的函數(shù) bpftrace -e profile:hz:99 { [ustack] count(); } # 統(tǒng)計進程調(diào)度延遲 bpftrace -e tracepoint:sched:sched_switch { [kstack] hist(args-prev-prio); }5.2 性能熱點火焰圖生成步驟采集數(shù)據(jù)perf record -F 99 -a -g -- sleep 60生成SVGperf script | stackcollapse-perf.pl | flamegraph.pl flame.svg分析要點看最寬的火苗注意平頂部分檢查調(diào)用鏈深度5.3 容器環(huán)境特殊處理在Docker中需要額外注意# 進入容器namespace nsenter -t PID -m -u -i -n -p # 查看cgroups限制 cat /sys/fs/cgroup/cpu/cpu.cfs_quota_us6. 長效防護機制6.1 監(jiān)控告警配置推薦Prometheus監(jiān)控指標(biāo)node_cpu_seconds_total{modeuser}process_cpu_seconds_totalrate(node_cpu_seconds_total[1m])告警規(guī)則示例- alert: HighCPUUsage expr: 100 - (avg by(instance)(rate(node_cpu_seconds_total{modeidle}[5m])) * 100) 85 for: 10m6.2 自動化排查腳本保存以下為cpu_diag.sh#!/bin/bash LOG_DIR/tmp/cpu_diag_$(date %s) mkdir $LOG_DIR # 基礎(chǔ)信息 top -b -n 1 $LOG_DIR/top.log ps aux --sort-%cpu $LOG_DIR/ps.log vmstat 1 10 $LOG_DIR/vmstat.log # 深度診斷 for pid in $(ps -eo pid,%cpu --sort-%cpu | awk $230 NR1 {print $1}); do echo PID $pid $LOG_DIR/deep.log cat /proc/$pid/cmdline $LOG_DIR/deep.log echo $LOG_DIR/deep.log strace -cp $pid $LOG_DIR/deep.log 21 done tar czf $LOG_DIR.tar.gz $LOG_DIR echo 診斷包已保存到 $LOG_DIR.tar.gz6.3 內(nèi)核參數(shù)調(diào)優(yōu)建議# 調(diào)整進程調(diào)度 echo kernel.sched_min_granularity_ns 10000000 /etc/sysctl.conf echo kernel.sched_wakeup_granularity_ns 15000000 /etc/sysctl.conf # 減少上下文切換 echo vm.dirty_ratio 10 /etc/sysctl.conf echo vm.dirty_background_ratio 5 /etc/sysctl.conf sysctl -p7. 避坑指南與經(jīng)驗總結(jié)不要立即kill進程先保留現(xiàn)場證據(jù)避免問題復(fù)現(xiàn)困難注意觀察間隔top默認3秒刷新可能錯過瞬時峰值建議用top -d 0.5 -c警惕監(jiān)控盲區(qū)某些CPU密集型操作可能在采樣間隔之間完成容器環(huán)境差異容器內(nèi)看到的CPU是宿主機的使用docker stats看到的才是容器真實的CPU限制多核CPU陷阱# 查看CPU親和性 taskset -pc PID # 綁定到特定核心可能提升緩存命中率 taskset -c 0,1 command歷史數(shù)據(jù)分析技巧# 查看過去24小時的CPU峰值時刻 sar -u -f /var/log/sa/sa$(date %d) | awk $NF 40 {print $1,$3}硬件因素排查# 檢查CPU頻率 cat /proc/cpuinfo | grep MHz # 查看CPU節(jié)流適用于云環(huán)境 grep -E thermal_throttle|clock_limiting /var/log/messages終極排查思路用戶態(tài)問題 → 分析應(yīng)用代碼/配置內(nèi)核態(tài)問題 → 檢查系統(tǒng)調(diào)用/驅(qū)動硬件問題 → 查看dmesg/溫度傳感器