本章談如何建構良好的監控與告警系統:什麼問題該打斷人類(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 對應
  • 把告警對齊「可達成的目標」,並確保監控支援「快速診斷」