無論是對外提供 IaaS PaaS SaaS 的雲公司,還是提供資訊科技服務的乙方公司,亦或是金融 製造等各行各業的資料中心、運維部門,我們的一個非常重要的合同承諾或考核評估指標就是:SLA(即:Service-Level Agreement 服務等級協定)。
而真正落地實現 SLA 的精確測量,最廣為人知的就是 Google 的 SRE 理論。
在 Google,會明確區分 SLO 和服務等級協定 (SLA)。SLA 通常涉及向服務使用者承諾,即服務可用性 SLO 應在特定時間段內達到特定級別。如果不這樣做,就會導致某種懲罰。這可能是客戶為該期間支付的服務訂閱費的部分退款,或者免費新增的額外訂閱時間。SLO 不達標會傷害到服務團隊,因此他們將努力留在 SLO 內。如果您要向客戶收取費用,則可能需要 SLA。
SLA 中的可用性 SLO 通常比內部可用性 SLO 更寬鬆。這可以用可用性數位表示:例如,一個月內可用性 SLO 為 99.9%,內部可用性 SLO 為 99.95%。或者,SLA 可能僅指定構成內部 SLO 的指標的子集。
如果 SLA 中的 SLO 與內部 SLO 不同(幾乎總是如此),則監控必須顯式測量 SLO 達標情況。您希望能夠檢視系統在 SLA 日程期間的可用性,並快速檢視它是否似乎有脫離 SLO 的危險。
您還需要對合規性進行精確測量,通常來自 Metrics、Tracing、Logging 分析。由於我們對付費客戶有一組額外的義務(如 SLA 中所述),因此我們需要將從他們那裡收到的查詢與其他查詢分開進行度量。這是建立 SLA 的另一個好處 — 這是確定流量優先順序的明確方法。
定義 SLA 的可用性 SLO 時,請注意將哪些查詢視為合法查詢。例如,如果客戶因為釋出了其移動使用者端的錯誤版本而超出配額,則可以考慮從 SLA 中排除所有"超出配額"的響應程式碼。
SLI 是經過仔細定義的測量指標,它根據不同系統特點確定要測量什麼。
常見的 SLI 有:
SLO(服務等級目標)指定了服務所提供功能的一種期望狀態,服務提供者用它來指定系統的預期狀態。SLO 裡不會提到,如果目標達不到會怎麼樣。
SLO 是用 SLI 來描述的,一般描述為:
比如以下SLO:
設定 SLO 時的目標依賴於系統的不同狀態(conditions),根據不同狀態設定不同的SLO:
總 SLO = service1.SLO1 weight1 + service2.SLO2 weight2 + …
為什麼要有 SLO,設定 SLO 的好處是什麼呢?
SLA = SLO + 後果
總 SLO = service1.SLO1 weight1 + service2.SLO2 weight2 + …
SLA = SLO + 後果
常見於通過 處理請求的服務或 API 提供的服務(如:物件儲存 或 API 閘道器)
如果有前端 js 探針監控,或撥測監控,那麼可以用前端使用者體驗 Apdex 作為 SLO。
Apdex 定義了一個效能標準,將應用程式使用者分為三個組:
例如,作為前端應用程式的 SLO,您可以指定希望 90% 的使用者 Apdex 都是 滿意
。
如,My WebApp
Apdex 公式如下:
100% * (apps.web.actionCount.category:filter(eq(Apdex category,SATISFIED)):splitBy("My WebApp")) / (apps.web.actionCount.category:splitBy("My WebApp"))
衡量手機 App (iOS 和 Android) 的可用性和可靠性的最重要指標之一是 無崩潰使用者率
。指的是沒有崩潰的情況下開啟並使用移動 APP 的使用者百分比。
因此,公式範例如下:
apps.other.crashFreeUsersRate.os:splitBy("My mobile app")
撥測可用性 SLO 表示撥測處於可用狀態下的時間百分比,或者,成功撥測佔執行的總測試數的百分比。
因此,公式範例為:
(synthetic.browser.availability.location.total:splitBy("My WebApp"))
成功率 = 成功的請求呼叫次數 / 總的請求呼叫次數
如:My service
的 成功率:
100% * (service.requestCount.successCount:splitBy("My service"))/(service.requestCount.totalCount:splitBy("My service"))
那麼,如果 My service
的關鍵 API 或請求需要計量,就可能是下面的公式:
(100%)*(service.keyRequest.successCount:splitBy(type("SERVICE_API") AND entityId("POST /login")))/(service.keyRequest.totalCount:splitBy(type("SERVICE_API") AND entityId("POST /login")))
ℹ️ 提示:
成功的請求最簡單的一種方式是:http 狀態碼為 2xx 或 3xx 的請求即視為成功。
還有一種,請求執行過程中沒有丟擲錯誤(紀錄檔或異常)的請求視為成功。
重點在於效能。
服務效能 SLO 表示 「fast」 服務呼叫佔服務呼叫總數的百分比,其中 「fast」使用自定義條件定義。例如:
ℹ️ 提示:
當然,上邊的 3s 也不應該是拍腦袋想的,而應該是例如基於過去一個月系統正常執行時 99% 百分位數的響應時間。
公式範例為:
(service:fastRequests:splitBy("My WebApp")) / (service:totalRequests:splitBy("My WebApp"))
錯誤率:是在給定的一小時間隔內,DB 的失敗 SQL 執行次數除以總 SQL 執行次數。
讀錯誤率:是在給定的一小時間隔內,DB 的失敗查詢 SQL 執行次數除以總 SQL 執行次數。
公式範例為:
可用性 % = 100% - Average DB Error Rate
或:
讀可用性 % = 100% - Average DB Read Error Rate
吞吐量失敗的請求:是指請求尚未超過給定 DB 吞吐量,卻被 DB 吞吐量限制,導致錯誤碼
吞吐量錯誤率:是在給定的一小時間隔內,給定 DB 的吞吐量失敗請求總數除以總請求數。
那麼,公式範例為:
吞吐量目標% = 100% -平均吞吐量錯誤率
SLI 為:
一致性違規率:是指在給定的 DB 中,在給定的一小時間隔內,對所選的一致性級別(按總請求數劃分)執行一致性保證時無法傳送的成功請求。
select 1 from dual
) 執行時間的 99% 百分位響應時間。那麼,範例公式為:
延遲目標% = 100% - 總的延遲時間和的次數 / (DB 總使用時間/1H)
如:過去 1 個月,總的延遲時間和的次數為 50 次,分母為:30 * 24 / 1 = 720
那麼:延遲目標% = 100% - 50 / 720 ≈ 93%
就是成功的訊息除以 MQ 接收的總訊息。
公式範例為:
(100)*((mq.rabbitmq.queue.requests.successful:splitBy("payment"))/mq.rabbitmq.queue.requests.incoming:splitBy("payment")))
例如,每小時正常執行時間百分比 = 100% - 單個 Host 範例處於不可用狀態的總時間(沒有超過多長時間才算不可用一說)百分比
不可用的定義可以是:
K8S 類是一類綜合系統,需要考慮如下目標
大致也是類似上邊的可用性目標。
這個通常非常高,比如:99.999999999%
可以簡單粗暴認為:只要有資料丟失的情況,就是沒達到目標。
典型案例就是騰訊的那次。
以 NAT 閘道器為例:
單範例服務不可用分鐘數: 當某一分鐘內,NAT 閘道器範例出方向所有封包都被 NAT 閘道器丟棄時,則視為該分鐘內該 NAT 閘道器範例服務不可用。在一個服務週期內 NAT 閘道器範例不可用分鐘數之和即服務不可用分鐘數。
可以根據不同的層次、元件設定不同的 SLO。
SLO 的監測是需要監控工具的支援。
常用的 SLO 包括:
EOF
三人行, 必有我師; 知識共用, 天下為公. 本文由東風微鳴技術部落格 EWhisper.cn 編寫.