Skip to main content

Command Palette

Search for a command to run...

閒聊設計 Slo 與 Sli

Updated
5 min readView as Markdown
閒聊設計 Slo 與 Sli

最近在閱讀 Implementing Service Level Objectives 這本書,作者 Alex 參與過 The Site Reliability Workbook 某些章節的寫作,所以很多概念跟之前幾本 SRE 相關書籍是有關連的。

這文章想介紹的是其中的第 12 章 A Worked Example,以及將學到的概念用在 OpenTelemetry Demo 的電商系統上。


A Worked Example

這是書中的零售網站架構,讓我來把這圖做個劃分

之前的章節一直提到 SLO 應該作為用戶旅程的工具。

所以這裡提出了一個核心觀點:SLO 應該基於用戶旅程來定義,這樣可以更好地對齊技術目標與業務需求。 將用戶分為三類:

  1. 外部客戶(如網站用戶)

  2. 其他服務作為用戶(如內部依賴的微服務)

  3. 內部用戶(如公司員工)

外部客戶:瀏覽和搜索產品

  • 用戶需求:客戶需要能夠快速瀏覽和搜索產品。

  • 相關組件:包括 CDN、Web 應用、產品數據庫、緩存、庫存微服務等。

  • 示例 SLO

    • 首頁加載延遲:99.9% 的請求在 2,000 毫秒內返回 2xx、3xx 或 4xx 狀態碼。

    • 搜索結果:99.8% 的搜索請求在 4,000 毫秒內返回 2xx 或 3xx 狀態碼。

關鍵觀點

  • SLO 應該考慮用戶的耐心,例如用戶對搜索結果的等待容忍度可能高於普通頁面加載。

  • 需要平衡性能與用戶體驗。

其他服務作為用戶:購買產品

  • 用戶需求:支付流程需要快速且可靠,因為這直接影響收入。

  • 相關組件:包括支付微服務、外部支付供應商等。

  • 示例 SLO

    • 結賬成功率:99.99% 的結賬請求在首次嘗試時成功。

    • 整體支付工作流程:99.93% 的結賬請求在整個流程中首次嘗試成功。

關鍵觀點

  • 當內部服務依賴外部供應商時,內部 SLO 必須考慮供應商的 SLA。

  • 需要計算多個目標百分比的相互影響,並設計適當的重試邏輯。

內部用戶

  • 用戶需求:內部工具(如數據分析應用和 Wiki)需要穩定可靠,否則會影響員工效率。

  • 相關組件:包括數據處理管道、內部應用、內部 Wiki 等。

  • 示例 SLO

    • 數據導出:90% 的數據導出嘗試在一個月內成功。

    • 內部 Wiki 可用性:工作時間內可用性達到 99.9%。

關鍵觀點

  • 即使是內部工具,也需要可靠性目標,否則會影響員工的工作滿意度。

  • 簡單的 SLO(如「是否可用」)對於第三方或開源軟體可能已足夠。

因此我們能把整個系統架構按照上面的案例畫分成這三區。

每個我們在更細緻的探索它們應用案例相關的 SLO 與 SLI

外部客戶

瀏覽和搜索產品

首頁加載延遲SLI

  • HTTP 響應時間是否小於 2000 ms。

  • HTTP 響應狀態碼是否為 2xx、3xx 或 4xx。

SLO︰99.9% 的請求應在 2000 毫秒內返回成功狀態。

(
  sum(rate(http_request_duration_seconds_bucket{le="2", status=~"2..|3..
"}[5m]))
  /
  sum(rate(http_request_duration_seconds_count[5m]))
) * 100

搜索結果

SLI

  • 搜索請求是否在 4000 ms內完成。

  • 搜索請求是否返回 2xx 或 3xx。

SLO

99.8% 的搜索請求應在 4000 ms內返回成功狀態。

# 計算符合 SLO 的成功率
(
  sum(rate(search_request_duration_seconds_bucket{le="4", status=~"2..|3.."}[5m]))
  /
  sum(rate(search_request_duration_seconds_count[5m]))
) * 100

為什麼明明圈起來的還有 Cache 和 Database,SLO 這裡卻沒用到呢?

  1. SLI 的核心目標是反映用戶體驗:

    • SLI 的設計是為了量化用戶旅程的成功與否,例如「首頁是否快速加載」或「搜索結果是否快速返回」。這些是用戶直接感受到的指標。

    • DBCache 是支持這些用戶操作的後端組件,對用戶來說是透明的。因此,我們通常不會直接將它們作為 SLI,而是通過高層次的指標(如 HTTP 響應時間)間接反映它們的性能。

  2. 內部組件的健康狀況通常通過內部監控來衡量:

    • DB 和 Cache 的性能(例如查詢延遲、cache hit rate等)可以作為內部的技術指標進行監控,但它們更適合作為服務可靠性的支持性指標,而不是直接的 SLI。

    • 如果 DB 或 Cache 出現問題,這些問題會反映在高層次的用戶操作(如頁面加載時間或搜索結果返回時間)中。

  3. 避免過於細化 SLI:

    • 如果將每個內部組件都單獨定義 SLI,會導致指標過於分散,難以管理和解釋。

    • 我們的目標是關注用戶價值,而不是每個內部組件的細節。

但我們可以設計 Dashboard link ,讓高階指標儀表板、連結至相關的細顆粒度的系統組件儀表板,協助分析。

-------------------------------------------------------
|      高層次指標(SLO):首頁加載時間                |
|   [首頁加載時間:99.9% 在 2000ms 內完成]           |
-------------------------------------------------------
|  相關內部指標(SLI):                              |
|   - DB 查詢延遲(99% 在 100ms 內完成)             |
|   - Cache 命中率(95%)                            |
|   - 外部 API 響應時間(99% 在 200ms 內完成)       |
-------------------------------------------------------

回呼一下小弟自己的出版內容OpenTelemetry 入門指南 第 9 章中曾提到,儀表板的設計,而 SLO 這樣的分層設計概念也是一樣的。

其他依賴的外部服務

整個支付流程(包括結賬、支付微服務、外部支付供應商)成功完成的比例。

支付流程成功率 = 支付微服務成功率 × 外部支付 API 成功率

結賬成功率

結賬成功率是指結賬請求中返回成功狀態(如 HTTP 2xx)的比例。

支付微服務

SLI

  • 支付請求是否在 1000 ms 內完成並返回成功狀態碼(2xx)。

  • 支付請求是否在首次嘗試時成功。

SLO

  • 99.99% 的支付請求應在 1000 ms 內成功完成。

  • 99.95% 的支付請求應在整個支付流程中成功。

外部供應商 API

SLI

  • 外部 API 請求是否在 2000 ms 內返回成功狀態碼(2xx 或 3xx)。

  • 外部 API 可用性是否達到指定 SLA。

SLO

  • 99.9% 的外部 API 請求應在 2000 ms 內返回成功狀態。

  • 外部 API 每月可用性應達到 99.95%。

# 計算支付流程成功率
(
  sum(rate(payment_service_requests_total{status="success"}[5m]))
  /
  sum(rate(payment_service_requests_total[5m]))
)
*
(
  sum(rate(external_payment_api_requests_total{status="success"}[5m]))
  /
  sum(rate(external_payment_api_requests_total[5m]))
)

為什麼支付這裡需要多個 SLI?

  1. 系統的複雜性
    現代系統(如微服務架構)涉及多個組件和依賴(如結賬微服務、支付微服務、外部支付供應商等)。單一的 SLI 無法捕捉所有這些組件的行為和性能。

  2. 不同層面的健康狀態
    每個組件的可靠性(如資料庫、API、Cache、負載均衡器等)都可能影響整體的用戶體驗。需要針對每個層面定義單獨的 SLI,才能精確定位問題。

  3. 從用戶體驗到內部依賴的監控

    • 用戶體驗層面:如支付流程的成功率。

    • 內部依賴層面:如支付微服務的延遲、外部支付 API 的可用性、database 查詢的成功率等。

    • 基礎設施層面:如負載均衡器的響應時間、Cache hit rate等。

只有當這些低層級的 SLI 都達到預期時,高層級的 SLO 才可能被滿足。

SLO 和多個 SLI 的關係

1. 單一 SLO,依賴多個 SLI

一個高層級的 SLO(如支付流程成功率 99.93%)通常依賴多個 SLI 的表現。例如:

  • 支付流程成功率 = 支付微服務成功率 × 外部支付 API 成功率

  • 如果任意一個 SLI 表現不佳,整個支付流程的 SLO 就可能無法達成。

2. 多個 SLO,分別追蹤不同維度

某些情況下,您可能需要為不同的關鍵指標設置單獨的 SLO。例如:

  • 支付流程成功率 SLO:99.93%。

  • 支付微服務延遲 SLO:95% 的請求延遲小於 1000 毫秒。

  • 外部支付 API 可用性 SLO:99.9%。

這樣可以更清晰地定義每個組件的責任範圍。

如何有效地管理多個 SLI?

  1. 分層管理

    • 高層級 SLI:直接影響用戶體驗的指標,例如支付流程成功率。

    • 低層級 SLI:內部系統的性能指標,例如支付微服務的延遲、外部支付 API 的可用性等。

  2. 自動化監控與告警 使用工具(如 Prometheus 和 Grafana)來自動化監控多個 SLI,並設置告警:

    • 當高層級 SLI(如支付流程成功率)下降時,觸發告警。

    • 當低層級 SLI(如 API 延遲)異常時,觸發更具體的告警。

  3. 關聯分析 在高層級 SLI 出現問題時,通過關聯分析低層級 SLI,快速定位問題源頭。

內部使用者

內部使用者的主要操作流程可以分為以下幾個階段:

  1. 資料查詢與處理(透過 Microservice D 和 Reporting 系統)

  2. 報表生成與查看(Reporting 系統)

資料查詢與處理

用戶行為: 使用者透過業務應用發送查詢請求,Microservice D 從資料庫中提取資料並進行處理,返回結果。

  • SLI:查詢所需報表與資料成功率

    • 定義:查詢請求成功返回結果的比例。

    • 測量方式:成功查詢請求數 / 總查詢請求數

    • SLO:99.8% 的查詢請求需成功

    • 如果太常查詢不到所需的即時資料也有可能是 ETL 的前半段出現問題。

  • SLI:查詢延遲

    • 定義:從用戶發送查詢請求到結果返回的時間。

    • 測量方式:查詢完成時間 - 查詢請求時間

    • SLO:

      • P80: 80% 的查詢需在 700ms 內完成。

      • P99: 99% 的查詢需在 1.5s 內完成。

內部用戶的範疇是否需要再細分?
例如,內部用戶可以分為「技術團隊」(如開發、運維)和「非技術團隊」(如業務部門)。這兩者的需求可能不同,例如:

* 技術團隊更關注內部系統的可用性(如 CI/CD 管道、監控工具)。

* 非技術團隊更關注業務支持工具的穩定性(如報表系統、CRM 系統)。


OpenTelemetry Demo 專案

Demo 專案剛好也是一個電商網站,其系統架構更加複雜一些。

先將用戶分類

  1. 訪客用戶 (Guest User)

  2. 購物用戶 (Shopping User)

  3. 支付用戶 (Payment User)

用戶類型與場景

訪客用戶 (Guest User)

    • 未登入的用戶,瀏覽產品、查看推薦商品。

      • 主要行為:瀏覽、產品搜索、推薦商品點擊。
  1. 購物用戶 (Shopping User)

    • 正在進行購物的用戶,將商品加入購物車,進行結賬。

    • 主要行為:加入購物車、結賬、選擇運送方式。

  2. 支付用戶 (Payment User)

    • 完成購物並進行支付的用戶。

    • 主要行為:提供支付信息、完成支付、收到訂單確認。

就能再根據這些場景去了解對應到哪些內部系統。

用戶場景

  1. 產品瀏覽場景

    • 用戶進入網站或應用,瀏覽產品目錄,查看產品詳情,並獲得推薦商品。

    • 涉及的服務:frontendproductcatalogservicerecommendationservice

  2. 購物車場景

    • 用戶將商品加入購物車,並檢視購物車內容。

    • 涉及的服務:frontendcartservicecurrencyservice

  3. 結賬場景

    • 用戶提交購物車,進行結賬,選擇運送方式,並確認訂單。

    • 涉及的服務:checkoutservicecartservicequoteserviceshippingservicefrauddetectionservice

  4. 支付場景

    • 用戶提供支付信息,完成支付,並收到訂單確認郵件。

    • 涉及的服務:paymentserviceemailserviceaccountingservice

設計用戶旅程的 SLO 與 SLI

(1) 產品瀏覽場景

目標 (SLO)

  • 產品瀏覽頁面加載成功率 ≥ 99.95%

  • 推薦商品 API 響應延遲 ≤ 200ms (P95)

相關 SLI

  1. 成功率

    • frontend 調用 productcatalogservicerecommendationservice 的成功請求數 / 總請求數
      PromQL:
    sum(rate(http_requests_total{service="frontend", status="2xx"}[5m])) 
    / 
    sum(rate(http_requests_total{service="frontend"}[5m]))
  1. 延遲

    • recommendationservice 的 P95 響應時間
      PromQL:
    histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{service="recommendationservice"}[5m]))

(2) 購物車場景

目標 (SLO)

  • 加入購物車成功率 ≥ 99.9%

  • 購物車頁面加載延遲 ≤ 300ms (P95)

相關 SLI

  1. 成功率

    • cartservice 的成功請求數 / 總請求數
      PromQL:
    sum(rate(grpc_requests_total{service="cartservice", status="success"}[5m])) 
    / 
    sum(rate(grpc_requests_total{service="cartservice"}[5m]))
  1. 延遲

    • cartservice 的 P95 響應時間
      PromQL:
    histogram_quantile(0.95, rate(grpc_request_duration_seconds_bucket{service="cartservice"}[5m]))

(3) 結賬場景

目標 (SLO)

  • 結賬成功率 ≥ 99.93%

  • 結賬流程完成時間 ≤ 1秒 (P95)

相關 SLI

  1. 成功率

    • checkoutservice 的成功請求數 / 總請求數
      PromQL:
    sum(rate(grpc_requests_total{service="checkoutservice", status="success"}[5m])) 
    / 
    sum(rate(grpc_requests_total{service="checkoutservice"}[5m]))
  1. 延遲

    • checkoutservice 的 P95 響應時間
      PromQL:
    histogram_quantile(0.95, rate(grpc_request_duration_seconds_bucket{service="checkoutservice"}[5m]))

(4) 支付場景

目標 (SLO)

  • 支付成功率 ≥ 99.9%

  • 訂單確認郵件發送成功率 ≥ 99.8%

相關 SLI

  1. 支付成功率

    • paymentservice 的成功請求數 / 總請求數
      PromQL:
    sum(rate(grpc_requests_total{service="paymentservice", status="success"}[5m])) 
    / 
    sum(rate(grpc_requests_total{service="paymentservice"}[5m]))
  1. 郵件發送成功率

    • emailservice 的成功請求數 / 總請求數
      PromQL:
    sum(rate(grpc_requests_total{service="emailservice", status="success"}[5m])) 
    / 
    sum(rate(grpc_requests_total{service="emailservice"}[5m]))

透過將使用者分類,給出業務場景,就能對照到系統架構與組件的依賴關係圖中,去設計出適合的使用者相關的 SLO。

總結

設計用戶旅程的 SLO 與 SLI 主要基於以下原則:

  1. 核心行為:針對用戶的關鍵操作(如瀏覽、購物、支付)設計 SLI。

  2. 多層次指標:從成功率、延遲和吞吐量等多角度衡量系統性能。

  3. 場景分解:根據不同用戶場景拆分指標,確保每個場景都有清晰的目標 (SLO)。

這樣的設計能幫助您清楚了解系統在不同用戶場景下的表現,並快速定位問題來源。

More from this blog

Get Your Hands Dirty on Clean Architecture CH5 Use Case

書本連結 前言 會挑這本書看的人,應該都是關心自己負責專案的軟體架構的人。不只希望開發的軟體能滿足客戶的明確需求,也希望能滿足可維護性(maintainability)的隱性需求,以及自己對結構與美觀習慣的要求。 要能滿足上述這些要求很難,因為專案通常不會按照計畫進行。可能變因有 deadline,最後的 API 與承諾的不同,又或者我們的設計無法很好的貼合需求的變化所需。。因此完美的架構只有在一

Jul 2, 20264 min read26
Get Your Hands Dirty on Clean Architecture CH5 Use Case

Claude Code 監控秘錄:OpenTelemetry(OTel/OTLP)實戰指南

稟告主公:此乃司馬懿進呈之兵書,詳解如何以 OpenTelemetry 陣法,令臥龍神算之一舉一動盡在掌握,知糧草消耗、察兵器效能、辨戰報異常,使主公運籌帷幄於大帳之中。 為何需要斥候情報? 司馬懿稟告主公: 臥龍神算(Claude Code)乃當世利器,然若無斥候回報,主公便如蒙眼行軍——兵器耗損幾何、糧草消費幾許、哪路斥候出了差錯,一概不知。臣以為,此乃兵家大忌。 無情報之弊,有四: 軍

Feb 19, 202610 min read241
Claude Code 監控秘錄:OpenTelemetry(OTel/OTLP)實戰指南
M

MicroFIRE

74 posts