SLI, SLO và error budget: đo độ tin cậy từ phía người dùng Trung cấp
Thời gian đọc ước tính: 11 phút
Vấn đề
Phần tiêu đề “Vấn đề”Dashboard CPU và memory đều xanh, Pod không restart, nhưng người dùng vẫn báo checkout lỗi. Một metric ở tầng máy chỉ cho biết máy còn chạy; nó không trả lời “bao nhiêu giao dịch người dùng hoàn thành đúng và đủ nhanh?”.
Nếu không thống nhất cách đo dịch vụ từ góc nhìn người dùng, đội vận hành và đội sản phẩm dễ tranh luận bằng cảm giác: bên này nói hệ thống ổn, bên kia nói trải nghiệm tệ.
SLI, SLO và error budget biến cuộc nói chuyện ấy thành một contract có thể đo. Chúng không hứa không bao giờ lỗi. Chúng giúp chọn mức tin cậy cần thiết, phát hiện khi chất lượng đang suy giảm và quyết định lúc nào ưu tiên ổn định thay vì thêm tính năng.
Khái niệm cốt lõi
Phần tiêu đề “Khái niệm cốt lõi”SLI (service level indicator) là một tỷ lệ hoặc phép đo về điều người dùng nhận được.
- Availability SLI của endpoint checkout trong 28 ngày: số request đủ điều kiện trả kết quả thành công chia cho tổng request đủ điều kiện.
- Latency SLI có thể là tỷ lệ request hoàn thành dưới 500 ms, không nhất thiết chỉ là một con số p95.
Tên metric không đủ; phải định nghĩa eligible requests, good requests, nơi đo, đơn vị và cửa sổ thời gian.
SLO (service level objective) là mục tiêu đặt lên SLI: ít nhất 99,9% request checkout đủ điều kiện phải “good” trong cửa sổ rolling 28 ngày. “Good” có thể yêu cầu cả status hợp lệ lẫn latency dưới ngưỡng, nhưng cần nêu rõ.
SLO là mục tiêu nội bộ về độ tin cậy; SLA thường là cam kết trong hợp đồng với hệ quả thương mại. Không nên dùng ba từ thay thế cho nhau.
Error budget là phần được phép không đạt SLO trong một cửa sổ. Với 10.000 request đủ điều kiện và SLO 99,9%, tối đa 10 request “bad” theo cách tính minh họa:
- Đã có 7 bad: còn 3.
- Thêm 5 bad trong cùng cửa sổ (giả sử tổng eligible không đổi): vượt budget 2.
Trong hệ thống thật, mẫu số tăng theo traffic, cửa sổ rolling trượt liên tục và phép tính integer/rounding cần được định nghĩa nhất quán.
10.000 request đủ điều kiện ├─ 9.993 good └─ 7 bad
Mục tiêu 99,9% → budget 10 bad → còn 3 badError budget ở đây là số lượng/tỷ lệ bad events, không tự động là số phút downtime. Chỉ có thể đổi sang phút nếu định nghĩa SLI theo thời gian hoặc đặt thêm giả định về traffic. Một giờ có 10 request và một giờ có 100.000 request ảnh hưởng rất khác nhau tới request-based SLI.
Cách hoạt động
Phần tiêu đề “Cách hoạt động”Bắt đầu bằng một user journey quan trọng, chẳng hạn “đặt hàng thành công”, không phải đo mọi endpoint như nhau. Xác định từ đâu người dùng thấy kết quả: load balancer, API gateway hay synthetic probe.
- Đo quá sâu trong service: có thể bỏ sót lỗi DNS, TLS, gateway và response bị cắt.
- Đo ở client: sát người dùng hơn, nhưng cần xử lý sampling, mạng người dùng và dữ liệu thiếu.
Có thể dùng nhiều nguồn đo, nhưng mỗi SLO phải ghi rõ nguồn chính.
Đang tải diagram…
Sơ đồ chỉ ra vì sao hai đội cùng tuyên bố “99,9%” vẫn có thể nói về hai thứ khác nhau: cùng một hệ thống, đo ở Service handler sẽ không bao giờ thấy request chết ở TLS hay gateway. Vì vậy mỗi SLO phải ghi kèm điểm đo, không chỉ con số.
Tiếp theo xác định eligible events. Có loại health check, traffic nội bộ hoặc request bị client hủy không? Nếu loại, lý do là gì và có che mất lỗi thật không?
Một 4xx do input sai thường không tính là lỗi server, nhưng 4xx do auth service hỏng có thể là trải nghiệm lỗi. Đừng chọn mẫu số chỉ để dashboard đẹp; hãy nhìn trace và ticket của người dùng để kiểm tra định nghĩa “bad” có đúng hay không.
Sau đó chọn mục tiêu vừa có giá trị vừa khả thi. 100% nghe hấp dẫn nhưng không để lại khả năng thay đổi hệ thống; mục tiêu quá thấp thì không bảo vệ trải nghiệm. Dùng dữ liệu lịch sử, kỳ vọng của người dùng và rủi ro kinh doanh để chọn SLO.
Một số chức năng có thể cần SLO riêng, chẳng hạn checkout khác với xem bài viết. Gộp tất cả vào một tỷ lệ có thể che lỗi của luồng quan trọng dưới traffic lớn của endpoint ít quan trọng.
Cuối cùng, theo dõi burn rate: budget đang bị tiêu nhanh tới mức nào so với tốc độ trung bình cho phép.
burn_rate = error_ratio / (1 - SLO)thời gian cạn budget = cửa sổ SLO / burn_rate- Burn rate 1: tiêu đúng hết budget vào cuối cửa sổ.
- Burn rate 14,4 trên SLO 30 ngày: cạn budget sau khoảng 2 ngày.
- Burn rate cao trên cửa sổ ngắn báo sự cố cấp tính; burn rate vừa phải nhưng kéo dài cho thấy chất lượng xấu dần.
Cấu hình alert thường dùng (SRE Workbook, SLO 30 ngày) kết hợp cửa sổ dài để tránh báo nhầm với cửa sổ ngắn để tắt alert nhanh khi đã hết lỗi:
| Burn rate | Cửa sổ dài / ngắn | Budget đã tiêu | Hành động |
|---|---|---|---|
| 14,4 | 1 giờ / 5 phút | 2% | Page ngay |
| 6 | 6 giờ / 30 phút | 5% | Page |
| 1 | 3 ngày / 6 giờ | 10% | Mở ticket |
Điều kiện alert là cả hai cửa sổ cùng vượt ngưỡng: cửa sổ dài chống báo nhầm, cửa sổ ngắn giúp alert tắt nhanh khi hết lỗi. Công thức SRE Workbook: budget đã tiêu = burn rate × cửa sổ alert / cửa sổ SLO. Ví dụ 14,4 × 1 giờ / 720 giờ = 2%.
Alert PromQL cho SLO 99,9% (budget 0,001), theo biểu thức mẫu của Workbook:
( sum(rate(http_requests_total{job="checkout", status=~"5.."}[1h])) / sum(rate(http_requests_total{job="checkout"}[1h])) > (14.4 * 0.001)and sum(rate(http_requests_total{job="checkout", status=~"5.."}[5m])) / sum(rate(http_requests_total{job="checkout"}[5m])) > (14.4 * 0.001))Thực tế nên tạo recording rule cho mỗi cửa sổ (1h, 5m, 6h, 30m…) để alert gọn và rẻ. Alert cần kèm SLI, SLO, budget còn lại và runbook.
Bảng “số chín” và giới hạn của nó
Phần tiêu đề “Bảng “số chín” và giới hạn của nó”Đổi sang thời gian chỉ để hình dung, vì lỗi thực tế thường là một phần request thất bại chứ không phải ngừng hẳn:
| SLO | Cho phép “lỗi toàn phần” trong 30 ngày | Trong 28 ngày |
|---|---|---|
| 99% | 7,2 giờ | 6,72 giờ |
| 99,9% | 43,2 phút | 40,3 phút |
| 99,95% | 21,6 phút | 20,2 phút |
| 99,99% | 4,32 phút | 4,03 phút |
Dependency nhân nhau: trần của SLO
Phần tiêu đề “Dependency nhân nhau: trần của SLO”Service gọi tuần tự ba dependency, mỗi cái 99,9%, và cần cả ba. Trần availability là 0,999³ ≈ 0,997, tức 99,7%, thấp hơn SLO của từng dependency.
Vì vậy không thể đặt SLO 99,9% cho service này nếu không có retry trong deadline, fallback hoặc loại bớt dependency khỏi đường găng. Xem timeout budget và retry, backoff, jitter. (Phép nhân giả định lỗi độc lập; lỗi tương quan làm kết quả khác đi.)
Error budget policy: thỏa thuận trước khi sự cố xảy ra
Phần tiêu đề “Error budget policy: thỏa thuận trước khi sự cố xảy ra”| Budget đã tiêu (cửa sổ SLO) | Hành động |
|---|---|
| Dưới 50% | Release bình thường |
| 50-100% | Tăng review rủi ro, ưu tiên sửa nguyên nhân lỗi đang lặp lại |
| Hết budget (100%) | Đóng băng release tính năng; chỉ nhận fix độ tin cậy cho đến khi budget hồi |
| Một sự cố tiêu hơn 20% budget | Bắt buộc postmortem có action item |
Ngưỡng trên là mẫu để chỉnh theo tổ chức; điều quan trọng là product và engineering ký trước, và ngoại lệ phải có chủ đích.
Khi nào dùng
Phần tiêu đề “Khi nào dùng”| Dùng SLO và error budget | Chưa cần |
|---|---|
| Service có người dùng thật và traffic ổn định | Prototype, chưa có người dùng |
| Cần quyết định cân bằng tốc độ release và độ tin cậy | Traffic quá thấp để tỷ lệ có nghĩa (1 lỗi là 10%) |
| Nhiều team phụ thuộc nhau | Chưa có số liệu để định nghĩa good/eligible |
Ví dụ thực tế
Phần tiêu đề “Ví dụ thực tế”Chạy phép tính đơn giản:
npx --prefix examples ts-node examples/src/slo-budget/slo-demo.tsDemo dùng 10.000 request, target 99,9%, 7 bad ban đầu rồi thêm 5 bad. Nó cố định mẫu số để dễ thấy phép trừ; với rolling window thật, mỗi request mới vừa làm tăng tổng eligible vừa có thể làm rơi request cũ khỏi cửa sổ.
Hãy thử đổi target thành 99,95%: budget giảm từ 10 xuống 5, nên cùng 7 bad đã vượt mục tiêu. Con số target vì thế là một quyết định sản phẩm/vận hành, không phải chỉ là cách tô màu dashboard.
Để kiểm chứng metric thật, lấy một mẫu request từ access log và tự phân loại good/bad theo contract, rồi đối chiếu với query dashboard. Test cả các trường hợp:
- response 200 nhưng business outcome sai;
- timeout ở gateway;
- client cancel;
- luồng có traffic rất thấp.
Một query Prometheus đúng cú pháp chưa chứng minh định nghĩa SLI đúng với trải nghiệm người dùng.
Checklist production
Phần tiêu đề “Checklist production”- Mỗi SLO ghi rõ journey, eligible, good, điểm đo và cửa sổ (28 hoặc 30 ngày).
- SLI tính bằng recording rule từ metric ở gateway hoặc load balancer.
- Alert burn rate hai cửa sổ (14,4 và 6 cho page, 1 cho ticket), kèm runbook.
- Error budget policy được product và engineering ký trước.
- SLO của service nhỏ hơn hoặc bằng trần tính từ dependency găng.
- Review định nghĩa good với ticket và trace thật mỗi quý.
Trade-offs
Phần tiêu đề “Trade-offs”Lợi ích
- Đưa tranh luận về độ tin cậy về một định nghĩa đo được và gắn với hành trình người dùng.
- Error budget giúp cân bằng tốc độ thay đổi với rủi ro vận hành.
- Burn rate giúp ưu tiên sự cố theo mức độ tiêu hao mục tiêu, không chỉ theo một điểm metric.
Giới hạn
- Chọn sai eligible/good có thể làm dashboard xanh trong khi người dùng vẫn lỗi.
- Cửa sổ rolling, traffic thấp và dữ liệu sampling khiến diễn giải tỷ lệ không đơn giản.
- SLO không thay thế việc điều tra nguyên nhân hoặc quyết định ưu tiên kinh doanh.
Sai lầm thường gặp
Phần tiêu đề “Sai lầm thường gặp”Tóm tắt
Phần tiêu đề “Tóm tắt”Tự kiểm tra: (1) Với 10.000 request và SLO 99,9%, có tối đa bao nhiêu bad? (2) Vì sao 200 không phải lúc nào cũng là good? (3) Tại sao một dashboard CPU xanh không chứng minh SLO checkout đạt?