Skip to main content

Command Palette

Search for a command to run...

閒聊設計 Slo 與 Sli

Updated
5 min read
閒聊設計 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

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

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

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

工程師的 Claude Code 實戰指南:從零開始到高效開發

工程師的 Claude Code 實戰指南:從零開始到高效開發 本文整合 Anthropic 官方 Best Practices 與社群實戰 Tips,帶你由淺入深掌握 Claude Code。 什麼是 Claude Code?為什麼值得學? 如果你還在用「複製程式碼貼到 ChatGPT,再複製答案貼回去」的工作流程,Claude Code 會讓你大開眼界。 Claude Code 是 Anthropic 推出的命令列工具,它直接活在你的 terminal 裡,能夠讀懂你的整個 codeb...

Feb 18, 20265 min read77
工程師的 Claude Code 實戰指南:從零開始到高效開發

System Design Interview Ch 12 Digital Wallet

確立問題與設計範疇 角色對話內容 面試者我們應該只關注兩個數位錢包之間的餘額轉帳操作嗎?我們是否需要擔心其他功能? 面試官讓我們只關注餘額轉帳操作。 面試者該系統需要支援多少 TPS(每秒交易次數)? 面試官讓我們假設是 1,000,000 TPS (每秒 100 萬次交易)。 面試者數位錢包對正確性有嚴格的要求。我們可以假設事務保證 就足夠了嗎? 面試官聽起來不錯。 面試者我們需要證明正確性嗎? 面試官這是一個很好的問題。正確性(Correctness)通常只有在交...

Feb 2, 202610 min read229
System Design Interview Ch 12 Digital Wallet

Claude Code 利用 Event-Driven Hooks 打造自動化開發大腦

在現代 AI 輔助開發中,我們不僅需要 AI 寫程式,更需要它懂規則、記性好,並且能自動處理那些繁瑣的雜事。透過 Claude Code Hooks 機制,我們可以介入 AI 的思考與執行迴圈,實現真正的「人機協作自動化」。 一、 動機與痛點:為什麼你需要介入 AI 的生命週期? 在預設狀態下,Claude Code 雖然強大,但它是「被動」且「無狀態」的,這導致了開發者常遇到以下痛點: 記憶重置 (Session Amnesia): 痛點:每次重啟終端機,AI 就像失憶一樣。 解法:你...

Jan 24, 20266 min read536
Claude Code 利用 Event-Driven Hooks 打造自動化開發大腦
M

MicroFIRE

71 posts