本章談如何建構良好的監控與告警系統:什麼問題該打斷人類(page)、什麼問題只該記下來。重點是符號 vs. 原因、白箱 vs. 黑箱、四個黃金指標、保持簡單。
術語先對齊#
- 監控(monitoring):蒐集、處理、聚合、展示系統的即時量化資料
- 白箱監控:以系統內部曝露的指標為基礎(log、JVM Profiling Interface、HTTP 內部統計端點)
- 黑箱監控:從使用者角度測試外部可見行為
- 儀表板(dashboard):以網頁形式總覽服務核心指標
- 告警(alert):寫給人看的通知,依嚴重度分為 page(緊急)、ticket(待辦)、email(資訊)
- 根因(root cause):軟體或人員系統中的瑕疵,修好即有信心相同事件不再以同樣方式發生
- 推送(push):對服務軟體或設定的任何變更
為什麼要監控#
- 長期趨勢:資料庫多大?日活躍使用者成長多快?
- 跨時間或實驗組比較:新版本是否變快?多加節點 cache 命中率提升多少?
- 告警:壞了,要立刻修;或快要壞了,需要儘速看
- 儀表板:對服務基本問題的解答,通常含「四個黃金指標」
- 臨機回顧分析(即除錯):延遲突然飆高,當時還有什麼事件?
呼叫人類(page)的成本很高:白天打斷工作流、晚上打斷睡眠。
告警過頻會讓人習慣性忽略,真正重要的 page 反而被噪音淹沒。有效告警的核心是「高信號、低噪音」。
對監控設合理期待#
Google 偏好「簡單而快」的監控系統,加上「強大的事後分析工具」。盡量避免「自動學習門檻」或「自動偵測因果」的魔法系統——除錯路徑必須讓全隊都看得懂。
- 10–12 人的 SRE 團隊通常有 1–2 人專責監控系統建置
- 不要讓人「盯著螢幕找問題」
- 偵測「使用者請求率異常」這類規則愈簡單愈好;容量規劃、長期趨勢分析則可容忍較複雜的脆弱性
- 複雜依賴鏈(「DB 慢就只報 DB,否則報網站慢」)的成功經驗有限——基礎建設變動快,依賴鏈容易陳舊
符號(Symptom)vs. 原因(Cause)#
好的監控要回答兩個問題:「壞了什麼」(symptom)和「為什麼」(cause)。
| 符號 | 原因 |
|---|---|
| 回 500 / 404 | 資料庫拒絕連線 |
| 回應變慢 | CPU 滿載 / 網路線壓壞 / 部分封包遺失 |
| 南極使用者收不到貓圖 | CDN 把某些 IP 列入黑名單 |
| 私密內容變成公開可讀 | 新版本推送把 ACL 弄丟了 |
「what vs. why」是寫出高信號、低噪音告警的關鍵分野。
黑箱 vs. 白箱#
- 黑箱:症狀導向,反映「現在正在發生」的問題——「我的服務真的壞了」
- 白箱:能看內部指標,可偵測即將發生、被重試掩蓋、或細微的健康變化
多層系統裡,一個人的「症狀」是另一個人的「原因」。例:對 DB SRE 來說「讀取慢」是症狀;對前端 SRE 來說它是「網站慢」的原因。
蒐集 telemetry 時,白箱不可或缺——否則無法分辨「DB 真的慢」與「網路出問題」。
頁面打斷人類用黑箱告警比較好:強制紀律「真的影響使用者才叫人」。但對「尚未發生但即將發生」的問題,黑箱無能為力。
四個黃金指標(Four Golden Signals)#
如果只能量四個指標,量這四個:延遲、流量、錯誤、飽和度。
- 延遲(Latency):成功與失敗請求的延遲要分開追蹤
- 500 錯誤可能很快回,但「慢失敗」比「快失敗」還糟
- 流量(Traffic):施加在系統上的需求量
- Web:QPS(可分靜態、動態)
- 影音串流:網路 I/O 或同時連線數
- K/V 儲存:交易與檢索次數
- 錯誤(Errors):明示(500)、暗示(200 但內容錯誤)、政策(超過合約延遲視為錯誤)
- LB 抓 500 可揭露完全失敗;但要抓「回了錯內容」需端到端測試
- 飽和度(Saturation):服務「多滿」?
- 對最受限的資源(記憶體、I/O)量
- 多數系統在達到 100% 之前就會退化,必須有「目標利用率」
- 延遲(特別是高百分位)通常是飽和度的領先指標
- 包含預測「DB 4 小時後磁碟會滿」這類訊號
注意長尾(Tail):分佈而非平均#
用平均數設計監控會被長尾騙。平均 100 ms、QPS 1,000 的服務裡,1% 的請求可能慢到 5 秒;若使用者要等多個後端,某後端的 99th 百分位常就是前端的中位數。
實作:把請求依延遲分桶,做成 histogram(桶邊界用近似指數成長,如 0–10、10–30、30–100、100–300 ms…)。
量測解析度#
不同面向需要不同粒度:
- 一分鐘量一次 CPU 載荷會錯過短暫但拖長尾的 spike
- 為 99.9% 年可用度服務每秒探測一次 HTTP 200 多此一舉
- 儲存空間檢查每 1–2 分鐘一次就夠了
高解析、低延遲的測量很貴。可採「伺服器端內部取樣 + 外部聚合」:每秒記 CPU 利用率到 5% 一桶,每分鐘聚合一次——看得到瞬時尖峰,又不爆預算。
盡量簡單但不過簡#
監控系統會像所有軟體一樣腐爛——複雜化會讓它變脆。
設計準則:
- 抓真實事件最頻繁的規則必須最簡單、最可預測
- 一季都不會用到的蒐集、聚合、告警設定,是移除候選
- 蒐集了但沒上儀表板、沒被告警引用的訊號,也是移除候選
- 不要把監控與其他事(深度 profiling、debugging、load testing、log 分析)糅進同一系統——以鬆耦合的 web API 串接會比較長壽
整合:對每個告警規則的拷問#
寫一條告警前先問自己:
- 它偵測的事是否緊急、可採取行動、正在或即將影響使用者?
- 我會不會在某些情境下知道它良性而忽略?哪些?怎麼避免?
- 是否確定使用者受影響?有沒有 drain、測試部署等該過濾掉的情境?
- 這個告警的回應是否需「智慧」?若只能機械式回應 → 不該是 page
- 是否有他人同時被叫起來?是否多餘?
信條:每次 pager 響,我都應能以「迫切感」回應;每次回應都需要智慧;page 應對應新或未見過的問題。把更多力氣花在「症狀」而非「原因」。
長期視角:兩個案例#
Bigtable SRE:告警過多的教訓#
早期 Bigtable SLO 訂在「合成 client 的平均延遲」,受長尾影響告警與 email 大量爆發、淹沒工程師時間——但真正影響使用者的反而被埋。
三管齊下:
- 同時投入改善底層儲存效能
- 暫時改用 75th 百分位作為 SLO 目標
- 關掉 email 告警(量太大無法分類)
換來喘息空間後,才能真正解決底層問題。
Gmail:可被腳本化的人類回應#
Gmail 早期長駐於原本為批次設計的 Workqueue 上,調度器有少數難解的 bug,導致每個 task 被「降排程」就會發告警——但 Gmail 有上萬 task。
爭議是:要不要先寫「自動戳一下調度器」的 hack?怕的是 hack 變永久、真正修復被無限延後。經理與技術主管要支持耗時的長期修復——機械式 page response 是紅旗,不願自動化通常意味著團隊對清理技術債缺乏自信。
「短期可用度下降」常是長期穩定性的策略性投資。不要把每個 page 視為孤立事件,要看整體 page 頻率是否朝向健康團隊與可持續系統。
結語#
健康的監控與告警管線是簡單、易推理的:
- 以症狀驅動 page,原因型告警退到除錯輔助
- 在堆疊愈上層監控症狀愈容易;但 DB 等底層飽和度仍需直接量
- email 告警價值有限,容易變雜訊——改用儀表板與 log 對應
- 把告警對齊「可達成的目標」,並確保監控支援「快速診斷」