【從一台 Server 到分散式架構】第 19 篇:系統有沒有生病怎麼知道?——監控、指標與告警
那天是半夜三點。
小明的手機震了兩下,是群組訊息——客服說有用戶反映「結帳一直轉圈轉不過去」。
小明睡眼惺忪地打開筆電,想查問題在哪。
他打開後端的程式碼看,沒有明顯錯誤。打開資料庫,看起來也正常。打開 Redis,也沒啥異常。
他不知道從哪裡看起。只能一個服務一個服務點進去翻 log,找有沒有 error 字樣。翻了二十分鐘,才發現是支付 API 的第三方服務回應超時,整個結帳 request 被卡死。
事後小傑說了一句讓小明印象很深的話:
「你花二十分鐘找到的事,應該要在三分鐘就告訴你。系統要能看見自己。」
生活化的比喻:體溫計 vs 等病人倒下
沒有監控的系統,像一個沒有任何儀器的病人。
你不知道他體溫多少、心跳多快、血壓幾點。你只能等他「倒下來」,才知道出事了。
有了監控,就像有了體溫計、心電圖、血壓計。你可以在情況惡化之前看見趨勢:體溫開始升高?心跳開始不規則?早點發現,早點處理。
系統監控的核心問題是:什麼數字能反映系統健不健康?
三個核心指標:QPS、延遲、錯誤率
幾乎所有後端系統,最關鍵的指標就是這三個:
1) QPS(Queries Per Second)——系統有多忙
每秒處理多少請求。
QPS 突然飆高可能是:流量突增、被攻擊、某個功能進入無限迴圈。
QPS 突然掉到零可能是:服務掛掉、負載平衡失效、部署中斷。
2) 延遲(Latency)——系統多快回應
通常用百分位數來看,而不是平均值:
- P50(中位數):一半的請求比這快
- P95:95% 的請求比這快——最能反映「大多數用戶的體驗」
- P99:99% 的請求比這快——反映「最慢的那 1%」
為什麼不看平均值?
假設 100 個請求,99 個都在 10ms 回來,1 個花了 1 秒。平均是 19.9ms,看起來很好;但那個等了 1 秒的用戶,體驗很糟。P99 會顯示為 1000ms,讓你看見問題。
3) 錯誤率(Error Rate)——系統多常出錯
HTTP 5xx 佔全部請求的比例。
正常系統,5xx 應該接近 0。若錯誤率突然從 0.1% 跳到 5%,就是出事了。
Prometheus:讓系統定期「量體溫」
監控系統需要有人「收數字」。Prometheus 是目前最常見的開源指標收集工具。
它的運作方式很直覺:
每隔 N 秒,Prometheus 去「拉取(scrape)」各個服務暴露的 /metrics 端點
→ 服務回傳:目前 QPS、延遲分佈、記憶體用量……
→ Prometheus 把這些數字存起來(時序資料庫)
應用程式只需要在 /metrics 端點回傳格式化的指標,Prometheus 就會定期來收。
# 典型 /metrics 輸出範例
http_requests_total{method="POST",status="200"} 1234
http_request_duration_seconds{quantile="0.95"} 0.012
這些數字隨時間累積,形成「時序資料(time-series data)」,讓你能看到「某個指標在某段時間的變化趨勢」。
Grafana:把數字變成看得懂的圖
光有數字不夠,人腦更善於看圖。Grafana 是一個「把 Prometheus 的數字畫成儀表板」的視覺化工具。
Grafana 讓你可以設計儀表板,同時看到多個服務的 QPS、延遲、錯誤率;時間軸一拉,馬上看出「凌晨三點那個尖峰是什麼時候出現的」。
告警:怎麼設才不會「狼來了」或漏報
有了數字,就要設告警。告警的問題通常不是「要不要設」,而是設得不好會有兩種災難:
問題一:狼來了(Alert Fatigue)
告警太靈敏,每隔幾小時就叫一次,但大多數時候查了都沒事。
結果:工程師開始忽略告警。真的出事時,也沒人認真看。
問題二:靜悄悄漏報
告警設太鬆,問題發生了半小時都沒叫。
結果:客服收到大量投訴,才知道出事了。
實務建議:
| 告警類型 | 設法 |
|---|---|
| 緊急(叫醒人) | P99 延遲 > 2s 且持續超過 5 分鐘;錯誤率 > 1% 持續 3 分鐘 |
| 警示(工作時間處理) | P95 延遲 > 500ms 趨勢上升;QPS 異常低(可能服務掛了) |
| 資訊(日常觀察) | 每日流量摘要、DB 查詢 P99 趨勢 |
關鍵原則:
- 告警要能操作(Actionable):收到告警,你知道要做什麼。「CPU 偏高」不夠好,「結帳 API P99 > 2s,持續 5 分鐘」好多了。
- 設持續時間門檻:不要一出現就叫,持續超過 N 分鐘才算真正的問題。
- 區分嚴重等級:緊急的叫手機、一般的發 Slack、低優先的只記錄。
除了應用層,還要監控什麼?
小明一開始只監控自己的 API,後來學到監控要分層:
應用層:QPS、延遲、錯誤率、背景任務執行次數
→ 我的程式有沒有正常處理請求?
基礎設施層:CPU、記憶體、磁碟 I/O、網路流量
→ 機器本身健不健康?
依賴服務層:DB 查詢時間、Redis 命中率、外部 API 回應時間
→ 我依賴的東西有沒有問題?
業務指標層:每小時新增用戶、成功付款數、課程完課率
→ 系統在「業務」層面是否正常?
最後一層「業務指標」很常被忽略。
技術指標一切正常,但如果「每小時付款成功數」突然掉一半,也是大事。監控不只是監控機器,也要監控業務是否健康。
小明落地的第一個儀表板
小明從最簡單的開始:
- 在每個服務加上 Prometheus 客戶端,暴露
/metrics - 設三個圖:QPS 折線圖、P95 延遲折線圖、5xx 錯誤率折線圖
- 設兩條告警:P99 > 1s 持續 3 分鐘 → Slack;錯誤率 > 2% 持續 5 分鐘 → 電話
光是這樣,半夜的事情就會在「第三分鐘」自動告知,而不是靠客服發現。
小結與預告
這篇小明學到的重點是:
- 三個核心指標:QPS(有多忙)、延遲(多快)、錯誤率(多常出錯)——用百分位數看延遲,而不是平均值。
- Prometheus + Grafana:Prometheus 定期收時序數字,Grafana 把數字畫成可視化儀表板。
- 告警的兩個坑:狼來了(太靈敏)vs 漏報(太鬆);告警要可操作、要有持續時間門檻、要分嚴重等級。
- 監控要分層:應用層 → 基礎設施層 → 依賴服務層 → 業務指標層,都要看。
監控讓小明知道「哪裡出事了」,但要知道「為什麼出事」,還需要另一個工具:Log 和分散式追蹤——同一筆請求跨了好幾個服務,出錯的那個環節到底在哪?
下一篇,我們來談分散式系統的「現場還原術」。