iT邦幫忙

2026 iThome 鐵人賽

DAY 26
0
IT Operation

AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨系列 第 26 篇

Day 26|CPU 正常,使用者卻說很慢:監控該看什麼?

  • 分享至 

  • xImage
  •  

上一篇比較了部署策略,也提到新版本是否可以繼續接收流量,需要靠成功率、錯誤率與回應時間判斷。

但如果 CPU 只有 30%、容器也都正常執行,使用者卻反映「訂單送出後要等很久」,接下來該看哪裡?

程式等待資料庫連線、外部 API 或鎖定釋放時,不一定會消耗大量 CPU,若只看資源使用率,就有可能會漏掉這些問題。

這篇會從 Metrics(指標)、Logs(日誌)與 Traces(追蹤) 出發,看看如何選擇監控能力,並從使用者的症狀找到需要處理的原因。


先確認哪項操作變慢

以下是一個假設案例。

訂單 API 執行在 ECS,透過 ALB 接收請求,建立訂單時會存取資料庫與庫存服務,平常回應時間的 P95 約為 300 毫秒,某次部署後升到 2 秒,但 CPU 仍維持在 30% 左右。

補充:P95 是什麼?
P95 是第 95 百分位數,把一段時間內所有請求的回應時間,從快到慢排列,P95 就是約 95% 的請求不會超過的時間。

例如 P95 為 2 秒,代表約 95% 的請求在 2 秒內完成,只有少數請求需要更長時間。

P95 不是平均回應時間,觀察 P95 可以避免平均值掩蓋部分使用者等待較久的情況。

這時直接增加 ECS Task,未必能改善問題,如果瓶頸在資料庫連線,增加 Task 還可能讓資料庫承受更多連線。

因此先確認是哪項操作變慢、是否伴隨錯誤,再檢查相關資源與相依服務,會比直接擴充容量更有依據。

接下來可以從三種監控資料觀察同一個問題:Metrics(指標) 用來發現整體異常,Logs(日誌) 協助查看個別操作的紀錄,Traces(追蹤) 則能找出請求的處理路徑與耗時。

https://ithelp.ithome.com.tw/upload/images/20261010/20183052hGGeM6gYwJ.png
圖:Metrics、Logs 與 Traces 的用途比較,圖中數據為示意,實際可取得的資訊取決於監控設定。


Metrics:什麼時候開始異常,影響多大?

Metrics 是一段時間內的數值,適合觀察趨勢、比較版本與觸發告警。

訂單 API 可以先看四件事:

  • 請求量:變慢時,流量是否突然增加?
  • 錯誤率:HTTP 5xx、逾時或訂單建立失敗是否增加?
  • 延遲:P95 是否升高,哪些操作受到影響?
  • 資源與等待狀態:CPU、記憶體、連線池等待是否同步變化?

在 AWS 上,可以透過 Amazon CloudWatch 查看服務內建指標,並收集應用程式自訂指標。

例如 ALB 的 TargetResponseTime,就是衡量請求送到後端後,到後端開始回傳回應標頭所花的時間。

另外 HTTP 成功也不一定代表業務成功,如果 API 回傳 200,內容卻是「訂單建立失敗」,只看 HTTP 5xx 就會漏掉問題,因此重要操作還需要記錄業務結果,並建立訂單成功率等業務指標。

比較新舊版本,必須先分得出版本

藍綠部署若使用不同的 Target Group(目標群組),可以分別觀察兩組延遲。

但在滾動部署期間,新舊版本的 ECS Task 可能同時接收請求,如果共用同一個 Target Group,ALB 的監控指標就會把兩個版本的結果一起統計,無法直接判斷是哪個版本變慢。

因此,需要在應用程式的監控資料中加入版本資訊(例如 v1、v2),並收集各版本的請求回應時間,才能分別計算 P95。

如果發現只有新版的 P95 明顯上升,而舊版正常、請求量也沒有明顯增加,就可以優先檢查新版程式及其相依服務。


Logs:那次操作發生了什麼?

Metrics 能看出「訂單 API 變慢」,Logs 則保留個別操作的結果與錯誤內容。

如果日誌只有 Request failed,排查時幫助有限,採用 Structured Logging(結構化日誌),可以把查詢需要的資訊分成欄位:

{
  "level": "ERROR",
  "service": "order-api",
  "version": "v2",
  "operation": "CreateOrder",
  "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "duration_ms": 2100,
  "error_code": "DB_CONNECTION_TIMEOUT"
}

把日誌送到 CloudWatch Logs 後,可以使用 CloudWatch Logs Insights 找出超過一秒的訂單請求:

fields @timestamp, version, duration_ms, error_code, trace_id
| filter service = "order-api"
    and version = "v2"
    and operation = "CreateOrder"
    and duration_ms > 1000
| sort duration_ms desc
| limit 20

這個查詢沒有只篩選 ERROR,因為慢請求也可能最後成功,前提是應用程式有記錄成功與失敗請求的耗時,而且 duration_ms 使用數值格式。

在本文案例中,若部分慢請求同時出現 DB_CONNECTION_TIMEOUT,就能進一步檢查資料庫連線取得過程。

這些業務欄位需要由應用程式輸出,日誌也應避免包含密碼、存取權杖與完整付款資料,而 Trace ID 適合用來關聯請求,不適合當成每次都不同的自訂指標維度。


Traces:時間到底花在哪裡?

當請求包含多個處理步驟,只看各自的日誌,很難還原完整的等待過程。

Distributed Tracing(分散式追蹤) 可以串起同一次請求的處理路徑,一次 Trace 包含多個 Span(追蹤區段),分別記錄操作的時間與狀態。

以下假設應用程式已為連線取得、資料庫查詢與下游呼叫建立對應的 Span,而且這些步驟依序執行:

步驟 耗時
驗證請求 20 毫秒
等待資料庫連線 1,700 毫秒
執行資料庫查詢 80 毫秒
呼叫庫存服務 150 毫秒

從這筆 Trace 可以看出,請求雖然成功取得資料庫連線,但光是等待連線就花了 1,700 毫秒,如果其他請求等待更久,超過連線池設定的等待時間,就可能發生前面日誌中的 DB_CONNECTION_TIMEOUT。

因此接下來應檢查連線池等待數、使用中的連線,以及新版程式是否正確釋放連線。

實際 Trace 可能包含多個互相重疊的 Span,因此不能直接把所有 Span 的耗時加總,當成整體請求時間。

在 AWS 上,可以使用 OpenTelemetry 產生與收集追蹤資料,再搭配 CloudWatch Application Signals 等工具查看服務效能與相依關係,不過應用程式需要先設定追蹤功能,如果想觀察「等待資料庫連線」等特定步驟,而自動追蹤沒有涵蓋,就需要額外加入自訂 Span。

當請求經過多個服務時,也需要傳遞 Trace ID 等追蹤資訊,並在日誌中記錄相同的 Trace ID,才能把不同服務的執行過程與錯誤紀錄關聯起來。


在 AWS 上,應該先建立哪些監控能力?

可以依照想回答的問題,選擇需要啟用與維護的能力:

監控需求 AWS 能力 額外設定與責任
查看 ALB 請求量、延遲與 HTTP 錯誤 CloudWatch 內建指標 建立面板、告警與適當門檻
查看 ECS 資源使用狀況 ECS 內建指標,需要更細資訊時評估 Container Insights 依需求啟用 Task/Container 層級監控,並管理額外費用
查詢應用程式的錯誤與慢請求 CloudWatch Logs/Logs Insights 設定日誌傳送、結構化欄位與保留時間
分析請求內部與跨服務的等待 Application Signals 搭配 OpenTelemetry 監測植入、資料傳送、上下文傳遞與取樣

對單一、處理流程簡單的服務,可以先建立服務指標、應用程式日誌與告警,當日誌已難以還原單次請求的等待位置,再加入追蹤。

不過是否需要 Traces 不能只看服務數量,一支重要的訂單 API,即使沒有拆成微服務,也可能依賴資料庫與第三方付款 API,仍值得追蹤關鍵步驟。

本文選擇服務指標、結構化日誌,再加上訂單路徑的追蹤 ,原因是需要比較部署版本,也需要區分資料庫連線等待與下游呼叫的耗時;相對地,團隊要承擔監測植入與資料收集的維護工作。

收集範圍也需要控制,日誌應設定保留時間,Trace 可以透過 Sampling(取樣) 減少資料量與成本。

取樣是指只保留部分請求的追蹤紀錄,例如設定 10% 的取樣率,代表每 100 筆請求大約只會保留 10 筆 Trace。


告警要能讓人採取行動

CPU 短暫升高、服務仍正常,和訂單持續失敗,最好不要使用相同的通知等級。

已影響使用者的失敗率、逾時與延遲,需要及時處理;容量逐漸不足但服務仍正常,則可以安排檢查與調整。

例如本文假設團隊要求訂單 API 的每分鐘 P95 不超過 1 秒,可以把「最近 5 個一分鐘區間中,有 3 個超過門檻」作為初始告警條件。

CloudWatch Alarm 支援這類 M out of N(N 個資料點中有 M 個違反門檻) 的判斷方式,可以避免服務偶爾變慢就立即發出告警。實際門檻仍需要依照服務能容忍的延遲與偵測時間調整。

另外,P95 也需要搭配請求量觀察,如果某分鐘只有幾筆請求,少數的慢請求就可能讓 P95 明顯波動,CloudWatch 因此提供低樣本處理設定,讓使用者決定樣本不足時是否繼續評估百分位數告警。

每個需要通知人員的告警,至少要交代環境、受影響的操作,以及對應的監控面板或排查文件,讓接手的人知道下一步要做什麼。


從症狀走到處理後的驗證

回到本文的假設案例,排查可以依序進行:

  1. 從可區分版本的指標,確認新版訂單 API 延遲上升。
  2. 從慢請求日誌找到連線逾時紀錄,並查看相關 Trace。
  3. 確認部分請求主要卡在取得資料庫連線,檢查連線池狀態與程式的連線釋放邏輯。
  4. 如果確認新版未正確釋放連線,依影響程度修正或退版,再觀察延遲、逾時率與連線池等待是否恢復。

這裡不能只憑 Trace 的等待時間就判定連線洩漏,也不能在退版完成後立即宣布問題解決,處理結果仍要回到使用者操作與相關指標驗證。


下一篇

監控能協助發現服務異常,但應用程式使用的資料庫密碼、API 金鑰,以及可疑的 AWS 操作,也需要另外管理。

下一篇會接著討論機密管理與操作稽核,看看權限設定完成後,還有哪些安全與事件處理責任需要安排。

參考資料


上一篇
Day 25|新版本怎麼上線,出問題又怎麼退回?
下一篇
Day 27|權限設好了,機密與安全事件怎麼管理?
系列文
AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言