EngineeringSolution ArchitectSecurity and Observability
Session 03 - SLA, SLO & SLI
3 min read8 lessons in this module
Definitions & Relationships
| Khái niệm | Định nghĩa | Ví dụ |
|---|
| SLI | Metric định lượng đo service quality | Tỷ lệ requests thành công (status < 500) |
| SLO | Target nội bộ cho SLI | 99.9% requests thành công trong 30 ngày |
| SLA | Cam kết hợp đồng, có penalty | 99.5% uptime, vi phạm → credit 10% |
| Error Budget | Lượng "lỗi cho phép" = 1 - SLO | 0.1% = ~43 phút downtime/tháng |
Quy tắc vàng
- SLO luôn strict hơn SLA: Nếu SLA = 99.5%, SLO nên = 99.9%
- SLI phải đo từ góc nhìn user: Đo ở load balancer/edge, không phải server-side
- Error budget là công cụ ra quyết định, không chỉ là con số
Cách Định Nghĩa SLIs cho .NET API
SLI Types
| SLI Type | Công thức | Phù hợp cho |
|---|
| Availability | Good requests / Total requests | APIs, web apps |
| Latency | Requests < threshold / Total requests | APIs cần response nhanh |
| Throughput | Successful operations / second | Batch processing |
| Freshness | Data updated within threshold / Total data | Caching, sync services |
Ví dụ: SLI cho Order API
csharp
public class SliMiddleware
{
private static readonly Counter<long> _totalRequests;
private static readonly Counter<long> _successfulRequests;
static SliMiddleware()
{
var meter = new Meter("SLI.OrderService");
_totalRequests = meter.CreateCounter<long>("sli.requests.total");
_successfulRequests = meter.CreateCounter<long>("sli.requests.successful");
}
private readonly RequestDelegate _next;
public SliMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
await _next(context);
if (context.Request.Path.StartsWithSegments("/api"))
{
_totalRequests.Add(1);
if (context.Response.StatusCode < 500)
{
_successfulRequests.Add(1);
}
}
}
}
public class LatencySliMiddleware
{
private static readonly Histogram<double> _requestDuration;
private readonly RequestDelegate _next;
static LatencySliMiddleware()
{
var meter = new Meter("SLI.OrderService");
_requestDuration = meter.CreateHistogram<double>(
"sli.request.duration", unit: "ms");
}
public LatencySliMiddleware(RequestDelegate next) => _next = next;
public async Task InvokeAsync(HttpContext context)
{
var sw = Stopwatch.GetTimestamp();
await _next(context);
var elapsed = Stopwatch.GetElapsedTime(sw);
if (context.Request.Path.StartsWithSegments("/api"))
{
_requestDuration.Record(elapsed.TotalMilliseconds,
new KeyValuePair<string, object?>("endpoint",
context.GetEndpoint()?.DisplayName ?? "unknown"));
}
}
}
Error Budgets & Burn Rate
Error Budget Calculation
SLO = 99.9% trong 30 ngày
Error Budget = 0.1% = 100% - 99.9%
Thời gian downtime cho phép = 30 * 24 * 60 * 0.001 = 43.2 phút/tháng
Burn Rate
Burn rate đo tốc độ tiêu hao error budget:
| Burn Rate | Ý nghĩa | Budget hết sau |
|---|
| 1x | Bình thường | 30 ngày (đúng kế hoạch) |
| 2x | Gấp đôi tốc độ | 15 ngày |
| 10x | Nghiêm trọng | 3 ngày |
| 36x | Critical | 20 giờ |
| 720x | Complete outage | 1 giờ |
Multi-window Burn Rate Alerts
yaml
- alert: SLO_HighBurnRate_Fast
expr: |
(
sum(rate(sli_requests_successful_total[1h]))
/ sum(rate(sli_requests_total_total[1h]))
) < (1 - 14.4 * 0.001) # 14.4x burn rate, 1h window
for: 2m
labels:
severity: P1
annotations:
summary: "Error budget burning 14.4x nhanh hơn bình thường"
- alert: SLO_HighBurnRate_Slow
expr: |
(
sum(rate(sli_requests_successful_total[3d]))
/ sum(rate(sli_requests_total_total[3d]))
) < (1 - 1.0 * 0.001) # 1x burn rate, 3d window
for: 1h
labels:
severity: P3
annotations:
summary: "Error budget đang tiêu hao đều đặn trong 3 ngày"
SLO Examples
Web API SLOs
| SLO | SLI | Target | Window |
|---|
| Availability | HTTP 2xx+3xx+4xx / Total | 99.9% | 30 days rolling |
| Latency (fast) | P50 < 100ms | 99% | 30 days rolling |
| Latency (slow) | P99 < 500ms | 99.9% | 30 days rolling |
Background Service SLOs
| SLO | SLI | Target | Window |
|---|
| Processing freshness | Messages processed < 30s age | 99.5% | 30 days |
| Throughput | Jobs completed / Jobs submitted | 99.9% | 30 days |
| Data freshness | Read model < 5s behind write | 99.0% | 7 days |
SLO-Based Decision Making
Error Budget Policy (mẫu)
Khi error budget cạn:
- Feature freeze - chỉ ship reliability improvements
- Mandatory rollback - deploy gây tăng error → rollback ngay
- Post-mortem required - mọi incident phải có postmortem
- Extra testing - tăng coverage, thêm load tests trước deploy
Trade-offs
| Quyết định | Pro | Con |
|---|
| SLO quá cao (99.99%) | User rất hài lòng | Tốn resource, chậm ship feature |
| SLO quá thấp (99%) | Ship nhanh, ít constraint | User không hài lòng, mất trust |
| Nhiều SLIs | Quan sát chi tiết | Phức tạp, khó maintain |
| Error budget policy strict | Reliability culture mạnh | Team frustrated, velocity giảm |
| Đo SLI ở edge | Chính xác từ góc user | Cần infra setup (LB metrics) |
| Đo SLI ở app | Dễ implement | Không thấy network issues |