阿里雲帳號購買 阿里雲國際站ECSCPU利用率100解決方案
第一章:CPU利用率100%不是“壞了”,而是“在忙”
當你在阿里雲國際站的 ECS(Elastic Compute Service)上看到 CPU 利用率長期徘徊在 100%,第一反應多半是擔心服務會立刻掛掉。但更準確的說法是:CPU 真的在滿負荷工作,只是“工作內容”可能是你期待的業務,也可能是某個程式失控,或某個依賴服務把請求堆成災。
很多人只盯著 CPU 指標,卻忽略了一件事:CPU=100%只是現象,根因要靠“負載型態”去判斷。是單核打滿還是多核都滿?是瞬時尖峰還是持續上升?是某段時間固定發生還是隨機?這些問題會直接決定你該先查程式、先查架構,還是先查系統層。
本文以“阿里雲國際站 ECS CPU 利用率 100% 解決方案”為核心,提供一套從觀察到修復、從短期止血到長期治理的思路。你不需要先是專家,也可以按照步驟逐步收斂問題。
第二章:先確認形態,再選擇排查路線
CPU 利用率 100% 的解決策略,取決於“形態”。我常把它分成三類:尖峰型、持續型、抖動型。你可以用監控面板的時間粒度查看最近 1 小時、6 小時、24 小時的走勢。
2.1 尖峰型:通常是排程或流量波動
如果 CPU 在某些時間段突然到 100%,過一段時間又回落,多半是:定時任務、批處理、文件/鏡像掃描、或突發流量導致的短期壓力。這類問題的解法常見於:調整排程時間、分批處理、限流、快取、以及在高峰前擴容。
阿里雲帳號購買 2.2 持續型:更可能是程式或系統異常
如果 CPU 從某個時間點開始就穩定 100%,幾乎可以判定有“持續性的忙碌來源”。常見原因:無限迴圈、異常重試風暴、序列化/反序列化爆炸、GC 過度、鎖競爭導致空轉、或某個背景任務卡在重算。
2.3 抖動型:可能是資源競爭或依賴瓶頸
CPU 不是一直 100%,而是上下波動,且伴隨延遲升高、錯誤率上升。這常與依賴服務(資料庫、中介、外部 API)瓶頸相關:你的程式為了等待依賴返回,反而在重試或忙等中消耗 CPU;或是連線池耗盡後不合理地重建連線。
第三章:定位根因:用“指標+日誌+現場狀態”三件套
阿里雲帳號購買 在解決 CPU 100% 之前,最忌諱的是“先改一堆參數再說”。真正有效的做法是:先用觀測資料確定“誰在吃 CPU”,再對症下藥。
3.1 看懂 CPU:用多維度指標而不是單一數值
在 ECS 監控裡,你通常能看到 CPU Utilization。若你能再配合查看負載分解更好,例如:系統層 CPU(kernel)、使用者層 CPU(user)、IO 等待(如果提供相關指標)。若你只能看 CPU,也要至少判斷是單核打滿還是多核都滿。
單核打滿常見於:某個線程跑滿(例如死循環、解析卡住、序列化重計算)。多核都滿則更可能是:並發過高、任務隊列積壓後被大量工作者同時拉起、或多進程/多容器同時重啟重算。
3.2 立刻進入現場:Top、Ps、Jstack/Profiler
當你已經確定是持續或可疑的型態,就需要進到實例內排查。以下是通用思路(不同系統命令可能略有差異,但方向相同)。
- 阿里雲帳號購買 先用 top/htop 看 CPU 最高的進程:記下 PID、執行檔名、以及是否有明顯的“單一進程長期第一”。
- 再用 ps 定位線程/執行緒(若是 Java/Go 服務特別常見):例如 Java 你可以取得線程堆疊(jstack)或用性能分析工具。
- 如果是容器化:先確認是哪個容器吃 CPU,避免誤判為主機問題。
很多時候你會立刻得到線索:例如某個 worker 進程佔用 90%+,或某個解析器服務突然成為第一名。這時候不要急著“降 CPU”,而是先確認它為什麼會跑得那麼忙。
3.3 查日誌:把“時間”對齊到 CPU 飆升點
CPU 100% 的時間點,就是你日誌的關鍵範圍。你需要做的是:
- 在系統日誌或應用日誌中找到與 CPU 飆升同一分鐘/同一小時的事件。
- 關注錯誤率上升、重試、超時、隊列堆積、或定時任務開始執行。
- 若看到大量“retry”、“timeout”、“reconnect”、“queue is full”等字樣,通常意味著外部依賴不穩或配置不合理。
日誌能告訴你“它在做什麼”。而 top/pid 能告訴你“它在用什麼”。兩者對齊後,根因往往會顯形。
第四章:常見根因與對應解法(從最常見到最致命)
下面列舉幾個在 ECS 上很常見的 CPU 100% 根因,以及可落地的處理方式。你可以對照你自己的排查結果,選擇最貼近的路徑。
4.1 無限迴圈或異常重試風暴
這是最常見的一類:程式邏輯錯誤導致死循環,或外部服務不可用時重試策略不加限制(例如沒有退避、沒有上限、沒有熔斷)。重試風暴會讓 CPU、網路、以及下游一起崩。
解決步驟:
- 立即在程式層加上重試退避(exponential backoff)與最大重試次數。
- 加入限流/熔斷:依賴不可用時直接失敗或降級,而不是把請求堆到佇列裡。
- 若是消息隊列消費端,檢查死信(DLQ)與重入機制,避免同一批訊息反覆觸發失敗。
驗收標準:CPU 回落且錯誤率不再持續上升;同時下游延遲也會改善。
4.2 並發過高、隊列堆積導致“同時工作者爆炸”
很多團隊在擴容後忘了調整消費者並發:例如隊列積壓後自動拉起大量 worker,導致每個 worker 都在競爭鎖、讀取同樣的資源,形成 CPU 風暴。
解決思路:
- 先把並發降到安全範圍(臨時止血),讓系統恢復穩定。
- 再重新設計:採用固定吞吐控制、分批消費、或以“每秒處理數”為核心的節流。
- 檢查是否存在不合理的重入或重複投遞導致同一訊息被多次消費。
4.3 GC 過度或記憶體壓力導致“忙於回收”
在 Java 等語言裡,如果記憶體配置不合理、對象分配速率過高,會出現頻繁 GC。表面上 CPU 高,實際上是 JVM 在回收。
排查要點:
- 查看 GC 日誌(若已開啟)。
- 觀察 Full GC 次數、停頓時間、以及堆使用率是否長時間處於高水位。
解決方式:
- 調整堆大小、年輕代/老年代比例(依你使用的 JVM 版本與垃圾回收器)。
- 優化物件分配:減少臨時物件、改進序列化方式、或引入快取。
- 若是緩存策略導致記憶體膨脹,要設定容量上限與淘汰策略。
4.4 解析/序列化/壓縮等 CPU 密集型任務沒有做隔離
例如在請求鏈路中直接做大檔案壓縮、加解密、或複雜 JSON 序列化,遇到高峰就會把 CPU 用光。更嚴重的是,服務同時承擔業務與重計算任務,導致延遲爆炸。
解決策略:
- 把 CPU 密集型工作從主請求鏈路移到非同步任務或獨立服務。
- 對結果做快取(例如相同輸入、相同輸出可直接命中)。
- 對上行資料做限制:檔案大小、並發、或頻率。
4.5 IO 不是主因卻被忽略:忙等與重試帶來 CPU 假性升高
有些情況下真正瓶頸在 IO:磁碟讀寫慢、網路延遲高、或資料庫慢查。但應用沒有合理超時和錯誤處理,導致它一直重試、一直等待卻又占用 CPU。
解決要點:
- 檢查連線池配置(最大連線數、等待策略)。
- 設定合理超時:連線超時、讀取超時、整體請求超時。
- 降低不必要的輪詢(polling),用事件驅動或阻塞等待替代。
4.6 系統層:路由、網卡中斷、監控/代理配置異常
少數但不罕見:某些 agent(監控、日誌採集、代理)配置錯誤會導致高 CPU。例如採集頻率太高、抓取大量檔案未做增量、或在檔案輪轉時反覆掃描。
解決方法:
- 檢查高 CPU 進程是否是 agent 或系統服務。
- 調整採集頻率與範圍,確保只做增量。
- 若是容器環境,確認監控範圍不會重複抓取。
第五章:立刻止血:你可以在今天就做的三步
當你已經看到 CPU 100%,不必等根因完全明朗。你需要先止血,讓服務可用、讓排查有空間。
阿里雲帳號購買 5.1 暫停或限流:先讓系統喘口氣
如果業務允許,先做限流或暫停部分高成本功能。目標不是永久解決,而是讓 CPU 回到可控範圍,避免故障擴大。
- 在入口層做限流(例如按 IP、按用戶或按請求類型)。
- 對非關鍵任務降級,例如只提供基本回應,延後計算。
- 若是消費端,先降低 worker 數量。
5.2 冷凍依賴:把外部抖動隔離掉
假設日誌顯示依賴服務 timeout 或 reconnect,大概率是外部不穩。你應該在應用端開啟熔斷或退避,降低對依賴的壓力。
在止血階段,最有效的是:快速讓失敗返回、避免無限重試。
5.3 擴容是否有效?要看負載形態
擴容是最直覺的做法,但並不是每次都有效。
- 若是突發流量引起且程式本身健康:擴容通常能快速改善。
- 若是程式死循環或重試風暴:擴容只會放大問題,CPU 更快把資源打滿。
- 若是 GC 過度或鎖競爭:擴容未必能立刻改善,甚至會讓總吞吐下降。
因此,擴容應該和排查並行:至少先確定不是“程式失控”。
阿里雲帳號購買 第六章:真正修復:針對根因做系統性改動
止血之後,你需要做“可持續的修復”。否則 CPU 100% 只是下次再來一遍。
6.1 如果是程式邏輯問題:修正並加上護欄
死循環、錯誤的條件判斷、或不合理的狀態機,都要回到程式碼修正。更重要的是加上護欄:
- 對外部調用加上超時與重試上限。
- 對任務執行加入最大耗時與取消機制。
- 對計算加入幂等與去重,避免重複處理。
6.2 如果是重試風暴:從“退避+熔斷”開始
重試風暴常被忽略,因為它在壓力來時才爆發。你要把重試變成“可控策略”而不是“無腦重試”。
- 退避:短時間內不要連續打爆。
- 熔斷:依賴短期不可用就立刻降級或快速失敗。
- 監控:把“重試次數/失敗率”納入告警。
6.3 如果是併發/隊列問題:讓吞吐可預期
把消費端並發與隊列堆積關聯起來,讓系統在壓力下能自我調節。
- 使用背壓(backpressure):佇列過長時降低消費或暫停部分任務。
- 為任務設計優先級:避免低優先級任務把資源耗盡。
- 分批與批處理:降低單次任務的 CPU 峰值。
6.4 如果是 GC/記憶體:做性能剖析而不是猜
GC 問題不建議靠“拍腦袋加大堆”解決。更好的做法是做 profiling,找出高分配率的熱點與可能的記憶體洩漏。
修復後你要同步更新 JVM 參數與服務健康指標,確保 CPU 回落是長期有效的。
6.5 如果是 CPU 密集任務:拆分、快取、離線化
當 CPU 是被真正的業務計算消耗時,最有效的手段通常不是盯著 CPU,而是改造工作流。
- 拆分鏈路:把耗時計算從同步接口移走。
- 快取:對可重用結果建立缓存。
- 離線化:把週期性或可延遲的任務用離線批處理完成。
第七章:驗收與告警:讓問題不再“悄悄回來”
修復完成後,你需要驗收兩件事:CPU 能否恢復到合理範圍,以及服務穩定性是否同步提升。
7.1 建立驗收指標
- CPU 指標:平均值與峰值(例如 5 分鐘平均不超過某閾值)。
- 延遲與錯誤率:請求延遲(p95/p99)與錯誤率是否同步下降。
- 隊列/重試指標:重試次數、超時次數、隊列堆積深度是否回落。
- 資源使用:記憶體、GC 次數、磁碟 IO 是否仍存在異常。
7.2 告警不要只盯 CPU:要盯“失控信號”
只盯 CPU 的告警容易造成誤導:CPU 飆升是結果,真正要告警的是“導致飆升的行為”。例如:
- 重試率瞬間飆升
- 超時率連續上升
- 佇列堆積速度快於消費速度
- 某進程 CPU 長時間居高不下(可用進程級告警)
把告警對準“失控前兆”,你就能更早介入,避免等到 CPU 已經 100% 才開始救火。
第八章:長期治理:把排查能力變成流程
解決一次 CPU 100% 是工程能力;讓它不再發生或更快定位,是治理能力。下面是我建議你固化成流程的內容。
8.1 建立“事件時間線”與復盤模板
每次 CPU 100% 都要記錄:何時開始、持續多久、當時主要進程是什麼、日誌中有哪些關鍵錯誤、你做了哪些止血操作、最後找到的根因是什麼。
復盤的價值在於:下次你不必重走同一段路。
8.2 性能基準與容量規劃
很多 CPU 100% 是在“沒有基準”的情況下發生的。你需要知道:
- 在常態流量下 CPU 佔用的合理範圍。
- 在峰值流量下 CPU 會如何變動。
- 不同批次大小、不同任務規模的 CPU 成本。
有了基準,你才能判斷“是異常”還是“正常放大”。容量規劃也會更精準。
8.3 代碼層的護欄:讓錯誤不會把系統拖死
在代碼中加入護欄,是最長期有效的解法。最常見的護欄包含:
- 所有外部依賴都要有超時、重試上限、退避與熔斷。
- 任務要有幂等與可重入設計。
- 後台 worker 要控制並發、支持停止或降級。
第九章:一個可直接套用的排查清單
如果你希望更快落地,下面提供一份“當 CPU=100% 立刻使用”的清單。你可以按順序走,通常能在短時間內逼近根因。
- 確認形態:尖峰/持續/抖動?
- 查看最近時間窗口日誌:CPU 飆升同一分鐘發生了什麼?
- 進入實例:用 top/ps 找出 CPU 最高進程/容器。
- 確認是否單一進程或單一線程打滿:若是,先查死循環/熱點計算。
- 阿里雲帳號購買 若是多進程/多容器:檢查是否重啟風暴、隊列積壓後並發上升。
- 阿里雲帳號購買 檢查重試與超時:看是否依賴不可用引發重試風暴。
- 若是 Java:看 GC 日誌、堆使用率,取得線程堆疊。
- 若是系統 agent:確認監控/日誌採集是否過量掃描。
- 阿里雲帳號購買 先止血:限流/降並發/熔斷,讓 CPU 回落,避免擴大故障。
- 再修復:按根因修改程式或配置,並補上護欄與告警。
阿里雲帳號購買 結語:CPU 100% 不是終點,而是一次工程檢驗
在阿里雲國際站的 ECS 上遇到 CPU 利用率 100%,最重要的是不要被數字嚇住。CPU 高通常代表系統在努力工作,只是工作方向可能錯了。你要做的,是把“現象”轉成“線索”,用監控、日誌、現場狀態共同定位,最後用限流、熔斷、優化並發、快取與性能調整讓系統回到可預期的運行區間。
當你把驗收指標與告警策略也一起補齊,CPU 100% 的事件就不會只是一次性的救火,而會變成提升穩定性與工程成熟度的契機。

