指南)
簡介面向Linux運維工程師的高CPU占用問題排查實戰(zhàn)文檔聚焦系統(tǒng)負(fù)載飆高時的定位與處理思路。資源系統(tǒng)梳理兩種常用排查方法一種通過top排序后結(jié)合top -H、線程ID轉(zhuǎn)十六進制、jstack查看線程狀態(tài)另一種通過ps -mp獲取線程耗時并排序再結(jié)合jstack打印堆棧二者均能快速鎖定異常線程與相關(guān)代碼。文檔還融入真實生產(chǎn)案例演示Java進程CPU占用率達(dá)到300%時的完整排查過程從初始top發(fā)現(xiàn)PID到最終定位線程堆棧避免盲目重啟服務(wù)同時介紹Zabbix、Nagios、阿里云監(jiān)控及“王教授”運維工具的告警機制強調(diào)監(jiān)控前置與主動發(fā)現(xiàn)的價值。資源為單個PDF文件大小147KB內(nèi)容精煉、操作命令明確適合運維人員和后端開發(fā)者隨時查閱文中方法無需圖形界面可直接在純命令行環(huán)境實踐。已有4448人學(xué)習(xí)下載對日常系統(tǒng)維護和故障應(yīng)急具有實際參考意義。1. CPU占用率高的排查先定位再動手別把玄學(xué)當(dāng)性能分析Linux系統(tǒng)中CPU占用率偏高可能是運維群里出現(xiàn)頻率最高的告警。很多人的第一反應(yīng)是登錄服務(wù)器敲top看到哪個進程%CPU高就kill -9哪個這套流程在壓測環(huán)境能交差到了生產(chǎn)環(huán)境經(jīng)常會翻車同一個進程的 CPU 統(tǒng)計跟監(jiān)控平臺對不上或者機器 load 已經(jīng)快拉滿top里 CPU 占用卻不到 60%。本文把一套在服務(wù)器上反復(fù)用的排查思路拆開講怎么從進程定位到線程、從用戶態(tài)挖到內(nèi)核態(tài)、再從現(xiàn)場判斷該調(diào)業(yè)務(wù)還是調(diào)資源適合負(fù)責(zé)后臺服務(wù)和容器平臺的開發(fā)運維也適合準(zhǔn)備 linux 面試題的同學(xué)在紙上把整套流程推演一遍。2. 用 top、ps、mpstat 把高占用進程和線程揪出來2.1 top 里的三個數(shù)%CPU、load average、us/sy 的正確讀法top是大家最熟的 linux 常用命令但多數(shù)人只看了兩個數(shù)第一行的 load average 和進程列表里的%CPU。這兩個數(shù)恰恰最容易誤讀。load average 后面的三個值分別代表過去 1 分鐘、5 分鐘、15 分鐘的平均活躍進程數(shù)?;钴S進程包含正在運行的 R 狀態(tài)進程和等待 IO 的 D 狀態(tài)進程所以 load 高不等于 CPU 高。一臺 4 核機器如果 load 是 4.0大致可以認(rèn)為跑滿但如果進程都在等磁盤load 到 8 也可能%CPU只有 20%。判斷是否 CPU 問題要以 CPU 狀態(tài)行和%CPU為準(zhǔn)load 只用來感受整體壓力趨勢。CPU 狀態(tài)行里重點看 us(user)、sy(system)、wa(iowait)、si(softirq)、st(steal)。us 高是業(yè)務(wù)代碼消耗sy 高是系統(tǒng)調(diào)用或內(nèi)核態(tài)消耗wa 高要轉(zhuǎn)向磁盤排查si 高要懷疑網(wǎng)絡(luò)包處理st 高則要考慮虛擬化宿主機搶占。進入top后先按數(shù)字鍵1把 CPU 展開成每個物理核的視圖如果只有個別核打滿說明問題可能出在單線程或中斷綁核后續(xù)排查方向完全不一樣。進程列表默認(rèn)按 CPU 排序但按P可以強制排序按H可以切換成線程視圖按c顯示完整命令行。這里花一分鐘記住top -H -p PID這個組合它會直接進入某個進程的線程視圖是定位單線程熱點最快的入口。2.2 ps 的 %CPU 只是平均值線程級視角要交給 pidstat很多新手只靠ps aux看 CPU這是第一個坑ps 報告的是進程從啟動到現(xiàn)在的平均 CPU 占用不是當(dāng)前實時值。一個剛崩潰重啟的進程哪怕現(xiàn)在把 CPU 打滿ps里也可能只顯示個位數(shù)百分比。所以ps適合拿來確認(rèn)進程存在、PID、父子關(guān)系不適合判斷當(dāng)前熱點。我一般會分兩步。第一步用ps做粗篩把所有進程按 CPU 占用排序看一眼到底哪個進程可疑ps -eo pid,ppid,%cpu,%mem,user,comm --sort-%cpu | head -n 20-e表示所有進程-o指定輸出列--sort-%cpu按 CPU 占用從高到低排序。這條命令 1 秒出結(jié)果適合在 CPU 飆高時先用它定一個嫌疑進程再用下面這條看該進程內(nèi)部的線程pidstat -u -t -p 12345 1 5pidstat來自 sysstat 包-u表示監(jiān)控 CPU-t顯示線程級別詳情-p 12345指定進程 PID最后的1 5表示每秒采樣一次、共采樣 5 次。輸出里每行對應(yīng)一個線程%usr是用戶態(tài)占用%system是內(nèi)核態(tài)占用%CPU是線程整體占用TID是線程號。這樣定位出來的線程號可以直接對照jstack、perf的調(diào)用棧結(jié)果把問題從“進程層面”壓到“線程層面”。這里有個很重要的換算概念單個線程的%CPU上限就是 100%相當(dāng)于占滿一個邏輯核一個進程顯示 300%說明它內(nèi)部有 3 個線程在并行跑滿。后續(xù)不管用perf還是看 Java 線程棧都要以 TID 為單位去對而不是用 PID。2.3 mpstat 看核間分布單核打滿和全核打滿是兩種病判斷完線程下一步要知道 CPU 壓力是不是均勻分布在所有核上。這決定了你要查的是單線程代碼問題、綁核問題還是多線程并發(fā)資源耗盡。命令是mpstatmpstat -P ALL 1 3-P ALL展示所有 CPU 核1 3表示每秒輸出一次、輸出三次。返回的表格里每一行是一個 CPU 核的實時占用%usr、%sys、%irq、%soft、%steal分別對應(yīng)不同來源??吹降慕Y(jié)果通常歸成兩類。一類是某個核長期超過 90%其他核卻很悠閑這種大概率是單線程的邏輯寫在關(guān)鍵路徑上或者內(nèi)核把中斷都塞給了一個核另一類是每個核都高這種要么是多線程死循環(huán)要么是鎖競爭導(dǎo)致所有線程都在自旋等待要么是宿主機 CPU 超賣。還有一種容易被忽略的情況業(yè)務(wù)進程每個核都只有 30% 左右但 CPU 總占用加起來很高。這種分布常見于日志寫入、壓縮、序列化這類影子開銷多的服務(wù)。不要只盯著最高的核看要按“總 CPU 時間消耗”去算賬。觀察現(xiàn)象可能原因下一步動作單核打滿其他核空閑單線程密集計算、中斷綁核查代碼熱點、查 /proc/interrupts所有核同步打滿多線程死循環(huán)、鎖競爭perf 采樣看內(nèi)核態(tài)函數(shù)各核 20%~40% 但總量高日志、壓縮、序列化等影子開銷逐一核對輔助進程與內(nèi)核線程%steal 明顯偏高虛擬機 CPU 被宿主機搶占檢查云主機規(guī)格與鄰居負(fù)載3. 從進程態(tài)挖到內(nèi)核態(tài)perf、vmstat 與中斷風(fēng)暴的排查路徑3.1 perf top 看熱點函數(shù)數(shù)據(jù)比直覺靠譜進程和線程定位完了只知道“誰”在燒 CPU還不知道“為什么”。這時候再猜就屬于玄學(xué)直接把采樣工具掛上去看內(nèi)核和用戶態(tài)函數(shù)分布。最簡單的是perf topperf top -p 12345它會按 CPU 采樣頻率對當(dāng)前進程的熱點函數(shù)實時排序默認(rèn)帶調(diào)用棧展開功能??吹接脩魬B(tài)函數(shù)名基本能判斷是不是死循環(huán)看到內(nèi)核態(tài)函數(shù)名也能猜個大概方向。比如native_queued_spin_lock_slowpath出現(xiàn)頻率很高多半是自旋鎖競爭do_softirq相關(guān)函數(shù)高要轉(zhuǎn)向網(wǎng)絡(luò)包處理finish_task_switch高說明線程切換本身消耗了大量 CPU進程內(nèi)線程數(shù)可能太多。如果希望保存下來慢慢分析可以用采樣方式perf record -g -p 12345 -- sleep 10 perf report-g記錄調(diào)用棧-p指定進程-- sleep 10表示采 10 秒就自動結(jié)束。perf report進入交互界面后會生成一張熱點調(diào)用樹按回車逐級展開能看到完整調(diào)用鏈。這條鏈路比任何日志都能說明問題。需要注意兩點。第一內(nèi)核符號可能需要 root 權(quán)限才能讀全普通用戶經(jīng)??吹揭欢裑unknown]生產(chǎn)環(huán)境可以臨時用 root 執(zhí)行受限命令后退出不要長期掛 root daemon。第二Java、Go 這類 JIT 或運行時語言perf 直接看到的用戶態(tài)符號往往是運行時自身配合jstack或py-spy把 TID 翻譯成業(yè)務(wù)線程名才算是閉環(huán)。3.2 vmstat 的 r 列和 cs 列上下文切換為什么會飆升perf能看函數(shù)級但很多機房環(huán)境不方便裝額外工具此時vmstat是個不需要安裝的備選。執(zhí)行vmstat 1 5關(guān)注五列r、cs、us、sy、wa。r 是當(dāng)前處于可運行狀態(tài)的進程數(shù)如果這個值持續(xù)大于 CPU 核數(shù)說明有一批進程在排隊CPU 確實不夠用cs 是每秒上下文切換次數(shù)這個值正常情況下每核幾百到一千多超過兩三萬就要警惕進程線程可能像抽風(fēng)一樣在搶時間片us 和 sy 分別是用戶態(tài)與內(nèi)核態(tài)的 CPU 時間占比wa 是 IO 等待占比。我最常碰到的場景是CPU 占用看著不高us 只有 20%但 sy 占了 40%cs 數(shù)值異常高。這種往往是短生命周期線程大量創(chuàng)建銷毀或者定時器、信號觸發(fā)太頻繁導(dǎo)致 CPU 大量浪費在“切換”而不是“干活”上。排查時用pidstat -w -t -p PID 1 5看每個線程的 cswch/s(自愿切換) 和 nvcswch/s(非自愿切換)自愿切換過多說明線程在等待鎖或 IO非自愿切換過多說明時間片不夠、線程數(shù)超過核數(shù)太多。3.3 把 D 狀態(tài)進程和 iowait 從 CPU 占用里剝出去很多人把 load 高和 CPU 高混為一談?wù)鎸嵤澜缋镉写罅?load 很高但 CPU 閑置的場景。罪魁禍?zhǔn)淄ǔJ?D 狀態(tài)進程也就是不可中斷睡眠狀態(tài)典型情況是進程在等磁盤 IO 或 NFS 響應(yīng)。D 狀態(tài)進程會計入 load average但不消耗 CPU 時間片所以top里 CPU 占用看著不高機器卻卡得不行。排查命令很簡單ps -eo pid,stat,wchan:30,comm | awk $2 ~ /^D/ {print}wchan:30顯示進程當(dāng)前等待的內(nèi)核函數(shù)名能看到它究竟卡在哪個內(nèi)核函數(shù)上。比如卡在wait_on_page_bit說明在等內(nèi)存頁回寫卡在nfs相關(guān)函數(shù)說明遠(yuǎn)端存儲有問題。看到一堆 D 狀態(tài)進程時不要再調(diào) CPU 配置先去查磁盤iostat -x 1看%util和svctm或者確認(rèn) NFS 掛載點是否可達(dá)。3.4 中斷風(fēng)暴ksoftirqd 和網(wǎng)卡多隊列還有一種 CPU 高是中斷帶來的表面上找不到用戶態(tài)進程但top里 si(軟中斷) 或者 hi(硬中斷) 不低同時 ksoftirqd 內(nèi)核線程占用會飆上去。這個場景在流量型服務(wù)上很常見網(wǎng)卡每收一個包就觸發(fā)一次中斷如果小包特別多中斷處理本身吃掉的 CPU 可能比業(yè)務(wù)代碼還多。先看中斷是否集中在某個核上cat /proc/interrupts左側(cè)是中斷號各列對應(yīng)每個 CPU 核收到的中斷次數(shù)。如果網(wǎng)卡相關(guān)中斷號只在 CPU0 上漲說明當(dāng)前驅(qū)動或配置把所有網(wǎng)絡(luò)中斷都綁到了第一個核這就是單核被打滿但其他核空閑的原因之一。常見做法是先確認(rèn)網(wǎng)卡是否支持多隊列用網(wǎng)卡工具查看隊列數(shù)量然后調(diào)整隊列數(shù)與 CPU 核數(shù)匹配讓多個核分?jǐn)偸瞻袛?。如果是虛擬化環(huán)境且驅(qū)動不支持多隊列可以嘗試開啟 RPS/RFS 這類軟件分發(fā)機制讓軟中斷均勻分散到各核避免單核成為瓶頸。這類問題的后續(xù)驗證也很直接mpstat -P ALL里各核%soft是否趨于均勻且用戶態(tài)業(yè)務(wù) CPU 是否順勢降下來。4. 對高 CPU 問題的常見處置手段從鎖競爭到進程配額4.1 死循環(huán)和忙等從熱點函數(shù)到止損措施代碼里出現(xiàn)死循環(huán)或忙等是 CPU 高最直接的原因。perf top顯示某個用戶態(tài)函數(shù)長期壓在頂部基本就能下結(jié)論。處理順序應(yīng)該是先止損、再定位、后修復(fù)。止損手段要看服務(wù)形態(tài)。能快速回滾的版本直接回滾不能回滾的臨時把并發(fā)調(diào)低比直接 kill 進程更安全因為 kill 會中斷所有請求影響面更大。常見做法是先用kill -STOP PID暫停進程確認(rèn)現(xiàn)場影響范圍后再決定是否kill -TERM。kill -9是最后的選擇因為它不給進程清理連接和釋放內(nèi)存的機會可能留下半關(guān)閉的 socket 或臟數(shù)據(jù)。止血后再按語言選工具C/C 用perf看調(diào)用棧Java 服務(wù)用jstack -l PID抓線程棧多抓幾次對比是不是同一個方法卡住Python 服務(wù)可用py-spy dump --pid PID拿到當(dāng)前正在執(zhí)行的 Python 函數(shù)名。定位到具體函數(shù)后再改代碼不要不停重啟重啟只是把黑匣子又蓋回去了。4.2 鎖競爭線程數(shù)不是越大越好另一個高發(fā)原因是鎖競爭。現(xiàn)象很典型CPU 占用高業(yè)務(wù)吞吐卻上不去perf top中自旋鎖相關(guān)函數(shù)排在前列火焰圖里鎖等待區(qū)域又寬又矮。很多人第一反應(yīng)是加線程實際上在高 CPU 密集場景下線程數(shù)遠(yuǎn)超核數(shù)就會產(chǎn)生大量上下文切換和鎖自旋CPU 全部耗在等鎖上活沒干多少。這類問題要先看鎖的粒度。把大鎖拆成細(xì)鎖、用讀寫鎖代替互斥鎖、減少持鎖期間的操作都是常用手段。線程池大小也不是簡單 2 倍核數(shù)就合理CPU 密集場景通常設(shè)為核數(shù)或核數(shù)加一IO 密集場景再放寬。這個問題也是 linux 面試題里反復(fù)出現(xiàn)的給你一個四核機器線程池開 100 個線程跑純計算吞吐能提升嗎答案是不能反而可能因為鎖競爭和切換開銷讓性能下降。如果代碼一時改不動可以先用taskset把進程綁定到固定核上限制它與其他進程爭搶但這只適用于單實例或?qū)ρ舆t不敏感的服務(wù)多實例場景慎用。4.3 日志滾輪和壓縮讓日志進程成了 CPU 大戶很多 CPU 高的問題不在業(yè)務(wù)進程而在日志鏈路上。新裝的 Linux 系統(tǒng)更容易踩這個坑systemd-journald 默認(rèn)把每個服務(wù)的輸出都收進 journal如果某個程序瘋狂打日志journald 的 CPU 會先飆起來。接著是舊日志壓縮歸檔日志越大壓縮進程消耗越高。排查時別只盯業(yè)務(wù)進程把systemd-journald、rsyslogd、logrotate的 CPU 都看一遍pidstat -u -p $(pidof systemd-journald) 1 5如果 journald 占用顯著先看是不是有服務(wù)一條條刷屏把日志級別調(diào)上去或者把無關(guān)輸出重定向到 /dev/null。journald 側(cè)可以調(diào)整/etc/systemd/journald.conf里的SystemMaxUse限制總?cè)罩救萘縍ateLimitIntervalSec和RateLimitBurst控制單位時間最多接收多少條日志修改后重啟 journald 生效。rsyslog 同步寫盤壓力大時可以改成異步隊列或者按日志量調(diào)整滾動策略避免一個日志文件膨脹到幾百兆后再一次性壓縮。這個環(huán)節(jié)經(jīng)常被忽略屬于排查順序里性價比很高的一步。4.4 用 systemd 配額給失控進程設(shè)上限當(dāng)進程暫時殺不得、代碼又改不動可以先把它的 CPU 占用限制住保住同一臺機器上其他服務(wù)。systemd 管理服務(wù)可以直接用運行時命令systemctl set-property your-service.service CPUQuota150%CPUQuota150%表示最多使用 1.5 個核的 CPU 資源底層對應(yīng) cgroup 的 cpu.max 配額150% 實際是 150000/100000 的比例關(guān)系。設(shè)置后立即生效重啟也會保留。想臨時看一下效果再決定去留可以執(zhí)行同樣的命令把配額改回空值去除限制。對不在 systemd 管理下的進程可以用cpulimit -p PID -l 50這類用戶態(tài)工具它通過暫停和恢復(fù)進程來控制 CPU適合應(yīng)急但不適合精度要求高的場景。要記住配額只是止損不是修復(fù)長時間用配額壓著有問題的進程會讓延遲劣化且難以察覺還是要留出時間窗處理根因。4.5 虛擬機 CPU steal宿主機搶走了本該屬于你的 CPU云服務(wù)器和虛擬化環(huán)境里還有一種“假高占用”的根因不在你機器內(nèi)部而在宿主機超賣。mpstat輸出里的%steal字段或者top狀態(tài)行里的st代表虛擬機申請 CPU 時間但被宿主機調(diào)度延后的比例。如果%steal持續(xù)超過 10%應(yīng)用的 CPU 占用和延遲都會肉眼可見地惡化但你在虛機里查任何進程都查不出問題。這種場景的處理思路很簡單不要調(diào)業(yè)務(wù)參數(shù)先調(diào)整部署位置。常見做法是遷移到低負(fù)載宿主機或者在購買資源時選擇限制超賣比例的實例規(guī)格。如果服務(wù)跨多臺機器優(yōu)先把流量切走如果無法遷移可以嘗試把業(yè)務(wù)線程的調(diào)度優(yōu)先級調(diào)低減少被宿主機搶占時的連鎖抖動但這個措施效果有限。判斷 CPU 高之前先看%steal能省掉后面一整輪業(yè)務(wù)層排查。5. CPU占用率排查避坑5 個容易翻車的誤判場景5.1 top 顯示占用正常但機器整體卡成 PPT現(xiàn)象top里各核%CPU只有 20% 左右但敲命令明顯卡頓SSH 窗口響應(yīng)延遲好幾十秒。原因CPU 狀態(tài)行里的 us、sy 都不高時要回看 load average 和 wa。常見根因是磁盤 IO 飽和進程大量進入 D 狀態(tài)排進 run queueload 被頂高而 CPU 真正花在“等 IO”上而不是“算”上CPU 百分比自然不高。解決用iostat -x 1看磁盤%util用ps -eo pid,stat | grep D數(shù) D 狀態(tài)進程確認(rèn)后再決定擴容磁盤、遷移數(shù)據(jù)還是排查慢存儲。不要把突破點放在 CPU 上那條路是死的。5.2 一個進程顯示 300% 或 800%以為是 bug 或中毒現(xiàn)象進程列表里某個進程%CPU顯示超過 100%甚至 900%第一反應(yīng)是數(shù)值異常或進程被種了礦機。原因top和pidstat的%CPU都是按核歸一化的100% 代表一個邏輯核打滿。多線程進程的多個線程并行運行占用多個核總和超過 100% 是完全正常的。解決用top -H -p PID切到線程視圖確認(rèn)是多個線程各占一部分還是某個線程單獨占滿。按 H 切換后如果所有線程加起來和進程總占用對得上說明是并行計算而非異常如果單個線程超過 100%反而要先懷疑進程綁核或者多個線程綁定同一個核再去查業(yè)務(wù)是否正常。5.3 strace 一掛上去CPU 占用反而降了現(xiàn)象現(xiàn)場怎么看怎么可疑strace 跟蹤幾秒后CPU 占用以肉眼可見速度下降讓人以為是誤報。原因strace 會攔截每次系統(tǒng)調(diào)用讓原本高頻的系統(tǒng)調(diào)用變慢整個程序的執(zhí)行節(jié)奏被拉低CPU 占用自然降下來。這不代表問題自動消失是干擾工具改變了測量對象。解決遇到這種情況就不要再用strace -p PID做長時跟蹤改用短窗口采集比如timeout 5 strace -f -c -p PID只看匯總統(tǒng)計或者換用perf采樣它對程序時序的影響小得多。記住排查工具的副作用本身也是排查的一部分。5.4 監(jiān)控平臺顯示 CPU 90%登錄服務(wù)器看卻不到 30%現(xiàn)象監(jiān)控告警 CPU 持續(xù) 90%但 SSH 上去執(zhí)行top和mpstat占用率只有 30% 左右兩邊數(shù)據(jù)對不上。原因監(jiān)控平臺通常按 1 分鐘或 5 分鐘周期聚合會把高峰期和低峰期平均top看的是當(dāng)前瞬間值兩者采樣窗口不同本來就有差異。另一個常見原因是監(jiān)控統(tǒng)計的是 cgroup 視圖而top看的是整機視圖容器場景尤其明顯。解決先把自己采集的周期拉長用pidstat -u 1 60連續(xù)記錄一分鐘看平均 CPU 和監(jiān)控平臺是否接近再確認(rèn)容器里用top時是否已經(jīng)進入了對應(yīng)容器的 PID namespace。數(shù)據(jù)對不齊時以長時間連續(xù)采樣為準(zhǔn)不要拿一個瞬間值反駁監(jiān)控平臺。5.5 內(nèi)存回收被誤判為 CPU 問題現(xiàn)象us 和 sy 都不高但 kswapd 內(nèi)核線程 CPU 起高系統(tǒng)整體響應(yīng)也變慢。原因內(nèi)存接近上限時內(nèi)核要反復(fù)掃描內(nèi)存頁做回收這個過程消耗 CPU 時間還會觸發(fā)直接回收進而阻塞進程。CPU 高只是表面現(xiàn)象根因在內(nèi)存。解決順手看free -h和vmstat的 si、so 兩列si/so 持續(xù)不為零說明已經(jīng)發(fā)生換頁。用dmesg -T | tail看有沒有 oom 相關(guān)記錄有的話優(yōu)先處理內(nèi)存泄漏和調(diào)低緩存上限而不是給 CPU 加配。內(nèi)存問題偽裝成 CPU 問題的比例不低CPU 排查的前三個步驟里應(yīng)該帶一眼內(nèi)存。6. 把排查流程固化成一個采集腳本再對照驗證結(jié)果第一次排查 CPU 高時憑記憶敲命令容易漏項等現(xiàn)場過去了再補采集就晚了。我現(xiàn)在養(yǎng)成的習(xí)慣是提前在機器上備一個采集腳本任何一個環(huán)節(jié)告警都先讓它抓現(xiàn)場。以下這個腳本會在當(dāng)前目錄生成帶時間戳的快照文件涵蓋 load、CPU 狀態(tài)、進程排行、線程排行四個維度#!/bin/bash stamp$(date %Y%m%d_%H%M%S) outdir/tmp/cpu_debug mkdir -p $outdir { echo snapshot $stamp uptime echo ----- CPU state ----- top -bn1 | head -n 8 echo ----- process top ----- ps -eo pid,ppid,%cpu,%mem,user,comm --sort-%cpu | head -n 15 echo ----- thread top ----- pidstat -u -t 1 1 | sort -k 9 -r | head -n 15 } $outdir/snapshot_${stamp}.txt echo saved to $outdir/snapshot_${stamp}.txttop -bn1是非交互模式只取一次快照pidstat -u -t 1 1采樣一秒鐘內(nèi)的線程占用用sort -k 9 -r按第 9 列%CPU排序。腳本要在疑似 CPU 高的第一時間執(zhí)行越早越能抓到當(dāng)時的真實負(fù)載而不是事后補測的近似值。如果問題持續(xù)而反復(fù)還可以用一段時間的趨勢記錄替代快照pidstat -u -t -p 12345 5 120 /tmp/cpu_debug/pidstat_$stamp.log 每 5 秒采一次、持續(xù) 10 分鐘后臺運行對比不同時段的線程熱點變化能看出是持續(xù)打滿還是周期性脈沖。驗證解決效果時不要只比較單個進程的 CPU 百分比要對照三組指標(biāo)負(fù)載狀態(tài)下降、上下文切換 cs 回落、應(yīng)用側(cè)延遲或吞吐恢復(fù)。CPU 占用降下來但請求延遲更差了說明只是把熱點壓住、根因沒動。我現(xiàn)在每次調(diào)整完配置都會先抓十分鐘的pidstat記錄和修復(fù)前的數(shù)據(jù)并排看確認(rèn)業(yè)務(wù)指標(biāo)也一起好轉(zhuǎn)才算結(jié)束。希望幫到你。本文還有配套的精品資源點擊獲取