iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0

昨天講了四個黃金訊號,今天要講另外兩套:USERED

剛開始看到這三套的時候覺得也太複雜了吧,為什麼差不多東西要出三套,到底要用哪一個?查了之後發現這個困惑是有原因的——它們確實有一半重疊,但是設計的時候想的對象不一樣。搞清楚「對象是誰」,選擇就不難了。

今天的故障開關:全部關閉

kubectl set env deploy/pricing BUG_SILENT_DISCOUNT=false LEAK_KB_PER_REQUEST=0
kubectl set env deploy/catalog BUG_N_PLUS_ONE=false

今天要比較節點之間、Pod 之間的資源差異,不要被故障干擾。

為什麼需要方法論

先說為什麼不能「想到什麼就監控什麼」。

Prometheus 裝好之後,光是 node-exporter 和 kube-state-metrics 就會給我們上千個指標。這時候的問題不是資料不夠,是不知道要看哪一個。

方法論的作用就是給我們一份檢查清單:面對一個新的服務,照著清單問三四個問題,就不會漏掉重要的東西,也不會被上千個指標淹沒。

它不是什麼高深的理論,就是清單而已。

USE:給資源用的

USE 是 Brendan Gregg 提出的,針對的是資源,也就是 CPU、記憶體、磁碟、網路、連線池這類「有容量上限的東西」。

對每一項資源問三個問題:

字母 問題 例子
Utilization(使用率) 這個資源有多忙? CPU 用了 70%
Saturation(飽和度) 有多少工作在排隊等它? 有 5 個執行緒在等 CPU
Errors(錯誤) 它有沒有出錯? 磁碟讀取失敗次數

使用率和飽和度的差別是關鍵

用餐廳比喻的話:使用率是「幾成的桌子有人坐」,飽和度是「門口排了幾個人」。

桌子坐滿(使用率 100%)但是門口沒人排隊,代表運作良好、剛好夠用;桌子坐滿而且門口排了二十個人,那才是真的出事了。只看使用率會漏掉後面那種情況。

CPU 尤其明顯:CPU 100% 不一定是問題,可能只是它正在認真工作。真正的警訊是「有多少任務在等 CPU」。

RED:給服務用的

RED 是 Tom Wilkie 提出的,他後來是 Grafana Labs 的共同創辦人。它針對的是請求驅動的服務,也就是「有人來請求、你回應他」這種東西。

字母 問題
Rate(速率) 每秒進來幾個請求?
Errors(錯誤) 其中失敗幾個?
Duration(耗時) 花了多久?

只有三個,很好記。而且這三個正好對應 Day 2 訂的 SLI:可用性 SLI 是 Errors 的反面,延遲 SLI 就是 Duration。這不是巧合,SLI 本來就該從使用者感受得到的東西挑。

三套的關係

對象 項目
USE 資源(CPU、記憶體、磁碟) 使用率、飽和度、錯誤
RED 服務(請求驅動) 速率、錯誤、耗時
四個黃金訊號 服務,但是多看一項資源 延遲、流量、錯誤、飽和度

排在一起就看得出來了:四個黃金訊號大致等於 RED 加上 Saturation。它比 RED 多要求你看一眼「離塞爆還有多遠」。

所以答案不是「選哪一個」,而是:

服務用 RED,資源用 USE,兩個都要有。

四個黃金訊號可以理解成 RED 的加強版,它提醒你別忘了資源那一面。

對三個服務做 RED

今天要回 Grafana 建面板,先把它開起來:

kubectl port-forward -n monitoring svc/kps-grafana 3000:80

一樣要另外開一個終端機視窗放著,然後瀏覽器打開 localhost:3000。忘記密碼的話再撈一次:

kubectl get secret -n monitoring kps-grafana \
  -o jsonpath="{.data.admin-password}" | base64 -d

我打算每個服務一列、三張圖。建面板的路徑跟 Day 9 一樣:右邊 Add 那塊點 Panel,再點 Configure visualization,查詢區右上角切成 Code

以 pricing 為例:

# Rate:每秒幾個請求
sum(rate(http_requests_total{job="pricing"}[5m]))

# Errors:失敗的比例
(sum(rate(http_requests_total{job="pricing", status=~"5.."}[5m])) or vector(0))
  / sum(rate(http_requests_total{job="pricing"}[5m]))

# Duration:P95
histogram_quantile(0.95,
  sum(rate(http_request_duration_seconds_bucket{job="pricing"}[5m])) by (le))

catalog 和 gateway 照著改 job 就好,三個服務就是三列。

這樣排的好處是橫向可以比較。三個服務的錯誤率放在同一個垂直位置,掃一眼就知道哪個特別高,不用一張一張點進去看數字。

https://ithelp.ithome.com.tw/upload/images/20260911/20180570PFRxJA8xUF.png

三個服務、三個指標、九張圖。做這張圖的時候我把 Day 9 學到的東西又用了一次,而且踩了幾個新的坑:

每一張的 Y 軸都要自己釘。 一開始我讓它自動縮放,Rate 的 Y 軸變成 5.56 到 5.63、Duration 變成 0.09749 到 0.09753——整張圖的高度是 0.04 毫秒。線在上面劇烈震盪,看起來像出了什麼事,其實那是雜訊冒充訊號。三張的設定分別是:

面板 Unit Min Max Threshold
Rate requests/sec 0 留空
Errors Percent (0.0-1.0) 0 0.05 0.01
Duration seconds (s) 0 留空 0.3

Errors 的 Max 設 0.05 是因為 Day 2 訂的可用性 SLO 是 99%,反過來就是錯誤率 1% 是紅線,上面留幾倍空間就夠了。設成 1(也就是 100%)的話,錯誤率從 0 漲到 3% 在圖上只有幾個像素。

只有一條線的面板,圖例要關掉。 Grafana 有兩個地方可以設定 Legend:查詢底下那個是決定「這條線叫什麼名字」,右側面板選項裡那個才是決定「圖例要不要顯示」。這九張圖每張都只有一條線,圖例寫什麼都是把標題再講一次,關掉還多出一行高度。等一下做 by (pod) 那張有兩條線時才需要它,那時候在查詢的 Legend 選 Custom{{pod}},Grafana 會自動帶入實際的 Pod 名字。

現在九張都是平線,這是對的。 故障全關著,這是基準線。它的價值不在好看,在於等一下打開故障的時候,我可以拿它來對照。

錯誤率那行為什麼要加 or vector(0)

Errors 那條查詢我一開始是這樣寫的,沒有 or vector(0)

sum(rate(http_requests_total{job="pricing", status=~"5.."}[5m]))
  / sum(rate(http_requests_total{job="pricing"}[5m]))

結果圖是空的。不是 0,是什麼都沒有。

我先跑分子確認:

sum(rate(http_requests_total{job="pricing", status=~"5.."}[5m]))

也是空的。原因很單純——我的示範服務根本不會回 5xxcommon.py 記的是實際的狀態碼,而 pricing 的每個端點正常情況都回 200,連 gateway 的結帳出錯時也是接住例外、回一個帶 error 欄位的 200。所以 status 這個標籤從頭到尾只有 "200"5.. 一個都比對不到。

但是為什麼是空的而不是 0? 因為 PromQL 的除法是在做序列比對:它要在左右兩邊找標籤相同的序列來配對。左邊一條序列都沒有,就沒有東西可以配,結果自然是空的。

or vector(0) 的意思是「左邊有東西就用左邊,沒有就給我一個常數 0」。加上去之後,沒有錯誤的時候會畫出一條貼在 0 的線,而不是一片空白。

這件事值得停下來想一下,因為**「沒有錯誤」和「查不到資料」在 PromQL 裡長得一模一樣,都是空的**。昨天忘記 by (le) 是空的、Day 8 標籤對不上也是空的,三個完全不同的錯,同一個症狀。差別在於,前兩個是我寫錯,這一個是真的沒有資料——而畫面上分不出來。

什麼時候看哪一套

實務上的順序是這樣:

  1. 先看 RED(或是 SLI)。 它是使用者感受得到的東西,也是唯一該用來叫醒你的東西
  2. RED 有異常,才往下看 USE。 這時候你在找原因,資源指標才有意義
  3. USE 正常但是 RED 異常 → 問題不在資源,可能在程式邏輯或下游服務
  4. USE 異常但是 RED 正常 → 先不要緊張,但是值得追蹤,它可能是未爆彈

第 4 種正是故障三的形狀:記憶體一直漲(USE 異常),但是使用者完全無感(RED 正常)。這種訊號到底要不要告警,是後面講告警的時候要處理的核心問題。

回頭把 Day 9 那句話講完整

Day 9 我列了一張「先不畫的圖」的表,把 CPU 和記憶體放進去,當時寫了一句「它們的位置是第二層,第一層的 SLI 圖告訴你有事,你才往下鑽」,然後說之後會給這個分層一個更完整的說法。

今天可以講完整了,那個分層就是這兩套方法論:

  • 第一層是 RED 或 SLI:有沒有事?這一層才可以拿來叫醒人
  • 第二層是 USE:為什麼?出事之後往下鑽的時候才看

所以那張表的意思不是「CPU 沒有用」,而是「CPU 不該出現在你半夜被叫醒時第一眼看到的畫面上」。

小結

  • USE 給資源、RED 給服務,兩個都要
  • 四個黃金訊號大約等於 RED 加上 Saturation
  • 使用率不等於飽和度,餐廳裡「坐滿」和「排隊」是兩回事
  • 分層:第一層 RED 判斷有沒有事,第二層 USE 找原因
  • PromQL 裡「沒有錯誤」和「查不到資料」長得一樣,都是空的,要靠 or vector(0) 分開

今天只做完了 RED 那一半。明天把 USE 實際做出來,順便做一個把服務擴成兩份的小實驗——那個實驗的結果跟我預期的完全不一樣。


上一篇
Day 10:PromQL 起步:rate、histogram_quantile 與四個黃金訊號
系列文
從看得到到看得懂:30 天在自架 K8s 上實踐可觀測性與告警11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言