AWS國際帳號代開 AWS EC2伺服器CPU突然100%解決方法
AWS國際帳號代開 第一章:先判斷「突然」到底意味著什麼
EC2 的 CPU 一旦衝到 100%,很多團隊第一反應是重啟伺服器。但如果你只做重啟,問題往往會以更快的速度回來。因為 CPU 100% 通常代表「某件事正在持續消耗運算資源」。重啟只是把現象暫停,卻沒有解釋原因。
所以第一步不是找按鈕,而是先把「突然」定義清楚:是某個時間點後才開始?是持續數分鐘還是數小時?是整台都飆高還是某個核心/單一進程飆高?
你需要把三件事弄清楚:
1)CPU 100% 的時間範圍:從 CloudWatch 指標看,該時間段是否跟部署、擴縮容、排程任務、流量暴增或憑證/資料庫變更同時發生。
2)是「CPU 使用率」還是「CPU 等待」:有時候看起來 CPU 100%,其實是 I/O 等待、網路重試、或 lock 造成的忙等。
3)是否是「整機」還是「特定進程」:只要能抓到占用 CPU 的進程來源,後面的方向就會明確。
第二章:用指標把範圍縮小(不要一上來就進機器瞎忙)
在開始進 SSH 前,先花幾分鐘看監控。這一步通常能省下 30 分鐘到 2 小時的盲查。
建議你在 CloudWatch(或你自己搭的監控)查看以下項目,對應同一時間窗:
・EC2 CPUUtilization:確認是否真的長時間 100%。
・NetworkIn / NetworkOut:是否有突發流量或異常連線(例如掃描或誤連)。
・StatusCheckFailed:如果有系統狀態檢查失敗,可能是硬體/OS 層問題。
AWS國際帳號代開 ・DiskReadBytes / DiskWriteBytes:如果磁碟 I/O 突增,CPU 高可能是被 I/O wait 放大。
・如果你用的是 Auto Scaling:檢查是否有擴縮容事件在同時間點發生。
・ELB/ALB 的 RequestCount / TargetResponseTime:若有流量暴增且延遲飆升,CPU 高多半是應用層。
一個簡單但很有效的判斷方式是:CPU 100% 同時伴隨網路與錯誤率上升,通常偏向外部流量或攻擊;若 CPU 100% 伴隨磁碟讀寫飆升與程式間歇性尖峰,可能是排程或資料處理卡住;若完全沒有外部異常,卻持續高 CPU,則更像是單一進程失控或資源瓶頸。
第三章:進機器後的「第一輪」排查清單
當你確定是某台 EC2 出問題,下一步才是進機器。
進入之後先做一輪快速觀察,目標是回答三個問題:現在誰吃 CPU?是否有大量重啟/崩潰重拉?CPU 使用是不是來自同一個方向(例如 user、system、iowait)?
3.1 先看系統負載:top、uptime、sar(或替代指令)
在 Linux 環境常見做法是先跑:
・top:觀察 CPU 是被 user 還是 system 吃掉;也看 load average 是否遠高於單核/多核的合理範圍。
・uptime:確認 load average 的趨勢。
・如果你有 sar(sysstat 套件):可以看一段時間的 CPU/IO/網路變化,對定位「突然」的起點非常有用。
關鍵不是只看到 100%,而是看分解後的來源。比如:
・user 高:通常是應用程式在計算。
・system 高:可能是大量系統呼叫、網路重試、檔案系統問題、或驅動/內核層開銷。
・iowait 高:CPU 高看似嚇人,實際上是等待磁碟;應用可能卡在讀寫或鎖住。
3.2 再看進程:找出最高 CPU 的 PID 和命令行
你要做的是快速定位「誰」。
常用方式是:
・top 直接看到 %CPU 最高的幾個進程。
AWS國際帳號代開 ・必要時用 ps -eo pid,ppid,cmd,%cpu,%mem --sort=-%cpu 取得更乾淨的排序。
然後你要做兩件事:
1)記錄進程的命令行與工作目錄:例如是你的 app、某個 worker、cron 程式、還是腳本。
2)看父進程(ppid)與是否有大量重拉:有些失控會形成「fork bomb」或反覆拉起。
這一步完成後,基本上問題就從「CPU 突然」變成「某個工作在某個時間點失控」。
3.3 檢查系統資源瓶頸:記憶體、磁碟、swap、檔案描述符
CPU 飆高常常是連鎖反應。你需要快速確認:
・free -m 或類似工具:是否已經大量使用 swap,或可用記憶體過低。
・df -h:磁碟是否滿了。磁碟滿可能導致應用反覆重試與寫入失敗,進而 CPU 變高。
・ulimit/檔案描述符限制:當應用耗盡 fd,可能在重試與錯誤處理中把 CPU 燒掉。
・dmesg(或 /var/log/messages):查看是否有大量 IO errors、硬體錯誤、或 network driver 警告。
你不需要把每個指標都看完,但至少要排除最常見、也最容易忽略的狀況:磁碟滿、swap 地獄、或大量錯誤重試。
第四章:最常見原因與對應解法(止血 + 修復)
下面列出遇到 CPU 100% 時,最常見的原因類型,以及你可以採取的具體處理方向。你不必全部照做,但建議你把它當成決策樹:先找類型,再選擇行動。
4.1 應用程式死循環或非預期的高負載(user CPU 高)
這是最常見的「真正原因」。程式可能因為:
・某次部署改了邏輯,導致迴圈條件錯誤。
・處理資料時遇到極端資料量或異常資料,導致解析/計算成本飆升。
・併發策略失控,例如同一筆任務被重複取走並重複處理。
AWS國際帳號代開 ・背景 worker 設定錯誤,造成無限重試。
止血策略通常是先把「罪魁禍首」停掉或降載:
・如果是可停的服務(如 worker / consumer),先停止 systemd 或容器中的 worker。
・如果是 web server,可以先把流量導回健康節點(例如讓 ASG 停止把流量導到這台)。
・對於支持限流的應用,先啟用限流或提高排隊時間,避免連環崩潰。
修復策略要回到程式與資料:
・檢查最近一次部署是否包含核心邏輯變更。
・查看 application log:找到 CPU 高期間的最後輸出、錯誤堆疊、或重試訊息。
・針對任務系統:確認重試次數、退避(backoff)、去重機制、以及死信(dead-letter)策略。
4.2 worker 或排程(cron、systemd timer)失控(間歇/固定時間尖峰)
很多 CPU 100% 不是完全隨機,而是跟排程有關。例如每小時、每天凌晨、或整點啟動資料同步。你在指標上可能會看到固定節奏的尖峰。
你要做的是:
・檢查 cron / systemd timer:看最近的觸發時間是否對上 CPU 飆高。
・看執行檔或腳本是否在同一時間同時跑很多個實例。
・檢查鎖機制:如果沒有分散式鎖,可能因為上一輪沒完成,下一輪又啟動。
止血可以先停掉該排程或調整頻率。
修復通常是補上鎖與冪等(idempotency),並加入執行超時與監控。例如超過 N 分鐘自動中止、並把該次任務送到待處理佇列而不是無限跑。
AWS國際帳號代開 4.3 資源瓶頸導致大量重試:資料庫慢、連線失敗、DNS 問題(user+system 皆可能)
當應用嘗試連線資料庫但失敗,它可能會進入高頻重試,造成 CPU 飆升。重試本身是計算,也會消耗 system 呼叫與網路連線。
判斷方式:
・application log 中是否出現大量「timeout」「connection refused」「retry」「DNS lookup failed」。
・網路指標是否在同時間上升,且可能伴隨大量短連線。
・資料庫的 CPU、連線數、或慢查詢是否同步惡化。
止血可以:
AWS國際帳號代開 ・暫時降低重試頻率或直接關閉重試(視風險)。
・在網路層加上快取或調整解析策略(例如避免每次重試都重新查 DNS)。
・把流量導到有能力處理的節點。
AWS國際帳號代開 修復則需要釐清瓶頸來源:
・查資料庫慢查詢、索引是否缺失。
・確認連線池配置:例如最大連線數、超時、與回收策略。
AWS國際帳號代開 ・確認 DNS/憑證更新機制是否在該時間點出現問題。
4.4 惡意流量或被掃描(可能 system 或網路相關 CPU 高)
有些 CPU 100% 並不是你內部程式,是對外開放服務被惡意打。常見狀況包括:
・持續的暴力嘗試連線、漏洞探測。
・大量失敗的 TLS 握手。
・反向代理(或應用)在處理惡意請求時耗盡資源。
判斷方式:
・看 NetworkIn/Out 是否暴增。
・看應用 log 是否有大量 4xx/5xx,或特定路徑被反覆命中。
・觀察是否有大量同來源 IP 短時間建立連線。
止血可以立即做:
・調整安全群組/網路 ACL,限制來源或封鎖明顯惡意 IP 段。
・在負載層或 WAF 啟用防護規則。
・對不必要的服務關閉對外端口。
修復是系統性防禦:WAF、防暴力、速率限制、最小暴露面,並把安全監控的告警提早。
4.5 磁碟 I/O 問題或磁碟寫滿(iowait 高)
當磁碟寫入滿或 I/O 非常慢,應用可能卡住,CPU 卻因為忙等、重試與錯誤處理變高。這種情況特別容易讓人誤以為「CPU 壞了」,其實是 I/O 造成連鎖反應。
你需要查:
・df -h:是否滿載。
・dmesg:是否有 I/O error。
AWS國際帳號代開 ・應用是否持續寫 log 或產生大量 core dump。
止血可以:
・清理臨時檔、調整 log 等級或 log 轉存策略。
・擴增磁碟容量,或移動 log 到較適合的儲存(依你的架構)。
修復是根治:設定 log rotation、限制 core dump,並對磁碟空間加告警。
第五章:一套「可重複使用」的處理流程(建議貼到團隊 SOP)
當你把排查做成流程,團隊在下次就不會陷入各自猜測。下面是一個你可以直接套用的 SOP(以 Linux 為例,但思路通用)。
5.1 止血(先保服務,再找原因)
1)確認 CPU 100% 持續時間與影響範圍:是否只有一台、是否有告警。
2)把流量導離:若你用 ALB/ELB,讓該 instance 停止接收流量或標記不健康(視你的架構)。
3)停止疑似失控的 worker/排程:先把高風險部分停掉,避免持續破壞資料。
4)保留快照與證據:至少保留 top 的瞬間資訊與相關 log 範圍(不用等完全修好才開始保存)。
5.2 取證(找出造成 CPU 的進程與行為)
1)定位 CPU 最高進程(PID、命令行、父進程)。
2)確認 CPU breakdown:user/system/iowait。
3)檢查當時的環境變更:部署、排程觸發、憑證更新、資料庫連線狀態。
4)查看應用 log 與錯誤:尤其是 timeout、retry、死循環或大量異常輸出。
5.3 修復(不只是讓 CPU 下來)
1)根因修補:修程式邏輯、調整排程、修索引、修重試策略或修安全設定。
2)加入保護機制:超時、限流、熔斷(circuit breaker)、最大重試次數、以及死信佇列。
3)補監控與告警:CPU、重試率、特定 log 關鍵字、磁碟空間與 I/O 指標。
第六章:針對 AWS 生態系的補充:監控、擴縮容、與部署的關鍵細節
很多 CPU 100% 不是孤立事件,而是跟 AWS 的自動化機制互相影響。
6.1 Auto Scaling:擴縮容可能把錯誤放大
如果你的應用在某些條件下會失控,Auto Scaling 可能看到 CPU 高而繼續擴容。結果是:你不但沒有解決,還把錯誤複製到更多節點。
這時候你需要:
・檢查 Scaling policy 的指標與閾值:CPU 高是否是結果而不是原因。
・在必要時先暫停擴縮容,讓你在受控範圍內修復。
・把告警分層:針對 CPU 高之外,也要看應用錯誤率、重試率、資料庫指標。
6.2 CloudWatch Agent 與系統指標:確保你看的不是「錯位的數據」
有些團隊第一次排查會被誤導,因為監控抓的指標粒度或單位不一致。例如有時候 CPU 指標延遲,或你同時有多個 agent 上報不同來源。
你可以做的簡單檢查:
・對照 instance 上手動的 top 與 CloudWatch 的 CPU 曲線是否一致。
・確認你使用的 agent 是否有採集失敗、或在 CPU 高時停止採集。
第七章:如何用程式與架構避免「再發一次」
修完當下的 CPU 100% 只是開始,真正重要的是讓同樣類型的問題不再重演。下面是針對常見根因的預防策略。
7.1 任務系統:重試要有退避、要有限次,還要有去重與死信
許多 worker 失控不是因為程式壞了,而是因為失敗處理沒有設計成熟。建議你確保:
・退避(backoff)與 jitter,避免所有節點在同一時間重試。
・最大重試次數,超過就丟到 dead-letter queue。
・去重或冪等(同一筆任務不會被多次處理造成爆炸)。
・加上執行超時(timeout),避免無限卡住導致 backlog 連鎖。
7.2 部署:建立回滾與金絲雀(canary),讓錯誤不會一口氣影響全部節點
如果你能在少量節點先跑新版本,就能及早發現 CPU 或錯誤率異常。金絲雀不是為了更花俏,而是為了減少 blast radius(影響範圍)。
同時也要確保:
・能快速回滾(至少到上一個穩定版本)。
・部署期間不要讓大量任務同時觸發(例如避免部署剛好跨過排程時點)。
7.3 資源與告警:不要只盯 CPU
AWS國際帳號代開 CPU 高很顯眼,但它往往是症狀。你更需要盯住「觸發症狀的前兆」。例如:
・資料庫連線數、慢查詢數量、錯誤率。
・重試率與佇列堆積長度(如果你用 SQS/Kafka 之類)。
・磁碟使用率、log 寫入速率、I/O error。
・ALB 的 4xx/5xx、延遲與吞吐是否異常。
第八章:把它寫成你的事故處理紀錄(讓下次更快)
每次 CPU 100% 事件,你都應該留下紀錄。不是因為要寫文書,而是因為真正的效率來自「可累積的判斷」。一份好的紀錄通常包含:
・事件時間線:何時開始、何時升高、何時解除。
・初始影響:幾台 instance、是否有服務降級或中斷。
・定位結果:是誰吃 CPU、CPU breakdown 是 user/system/iowait 哪個主導。
・根因:程式邏輯錯、排程重入、資料庫慢、惡意流量、磁碟問題等。
・修復與驗證:做了哪些改動、如何驗證 CPU 回落且穩定。
・預防措施:告警補到哪裡、加了哪些保護機制。
當這些資訊在團隊裡沉澱,你下次遇到同樣現象時,就不會每次都從頭猜。
結語:CPU 100% 是症狀,不是結論
AWS EC2 的 CPU 突然 100% 看似嚇人,但其實它是一個很清楚的訊號:系統正在被某種行為逼到極限。真正的差別不在於你是否「把 CPU 壓下去」,而在於你能不能在壓下去的同時,找到那個造成它的原因。
你可以把本文的思路濃縮成一句話:先用監控縮小範圍,再用進程定位罪魁禍首,接著用日誌與資源指標對上時間線,最後用修復與預防讓它不再回來。
下次當 CPU 又衝到 100%,你不需要慌張重啟;你要做的是把「突然」變成「可追蹤、可修復、可預防」。

