3. SLO 基础:服务等级目标 (SLO) 定义、SLI 与 SLO 的关系、常见的 SLO 指标类型
在构建自动化发布策略之前,必须建立一套可量化的服务质量衡量体系。SLO(Service Level Objective,服务等级目标)正是这套体系的核心决策依据。它不是一个模糊的“系统要稳定”,而是一个精确的、可验证的数值承诺,直接决定了你的部署流水线何时可以放行、何时必须熔断。
3.1 核心概念:SLI、SLO 与 SLA 的三角关系
理解 SLO 的前提是区分三个经常被混用的术语:SLI(服务等级指标)、SLO(服务等级目标)和 SLA(服务等级协议)。它们构成了从测量到承诺的完整链路。
| 术语 | 定义 | 典型示例 | 责任主体 |
|---|---|---|---|
| SLI | 对服务某个维度的实际测量值,是原始数据 | 过去 5 分钟 P99 延迟 = 210ms | 监控系统 |
| SLO | 对 SLI 设定的目标阈值,是内部承诺 | 月度 P99 延迟 ≤ 200ms 的比例 ≥ 99.9% | 服务团队 |
| SLA | 对客户公开的法律承诺,通常附带赔偿条款 | 月度可用性 ≥ 99.99%,否则退还 10% 月费 | 法务 / 业务 |
关键原则:SLO 必须比 SLA 更严格。如果 SLA 承诺 99.99% 可用性,SLO 应设为 99.995%,预留出错误预算消耗的缓冲空间。SLO 是工程团队的内部驾驶仪表盘,SLA 是面向客户的法律红线。
3.2 SLI 与 SLO 的关系:测量与承诺的闭环
SLI 是“事实”,SLO 是“标准”。两者通过错误预算机制形成闭环:SLI 持续上报,SLO 定义可容忍的失效边界,超出边界的部分即为消耗的错误预算。当错误预算耗尽,部署频率必须降低或暂停。
实践建议:在服务目录中为每个服务至少定义 2 个 SLO(延迟 + 可用性),并将错误预算剩余比例作为部署流水线的准入门禁。当错误预算低于 50% 时,自动降低部署频率;低于 20% 时,自动阻断非紧急发布。
3.3 常见的 SLO 指标类型
并非所有指标都适合作为 SLO。好的 SLO 指标必须满足三个条件:用户可感知、可精确测量、可设定合理阈值。以下是生产环境中使用最广泛的四类指标。
3.3.1 可用性 (Availability)
衡量服务是否正常响应请求。通常以“成功请求占总请求的百分比”来定义。对于有状态服务,还需考虑会话连续性。
- 计算公式: (总请求数 - 失败请求数) / 总请求数 × 100%
- 典型 SLO: 月度可用性 ≥ 99.99%
- 常见陷阱: 仅监控 HTTP 状态码 5xx,忽略了业务逻辑错误(如返回 200 但实际数据错误)。
3.3.2 延迟 (Latency)
衡量请求从发出到收到完整响应的时间。由于延迟分布通常呈长尾特征,必须使用百分位值而非平均值。
- 关键百分位: P50(中位数)、P95、P99(尾部延迟)。
- 典型 SLO: P99 延迟 ≤ 200ms,且月度达标率 ≥ 99.9%
- 常见陷阱: 只监控 P50 而忽略 P99,导致长尾延迟被掩盖。
3.3.3 吞吐量 (Throughput)
衡量服务在单位时间内处理的请求量。对于弹性伸缩和容量规划至关重要。
- 计算公式: 请求总数 / 时间窗口(通常为 1 分钟)
- 典型 SLO: 每分钟处理请求数 ≥ 10,000 RPS
- 常见陷阱: 吞吐量 SLO 必须与延迟 SLO 联合使用,避免“高吞吐但高延迟”的虚假繁荣。
3.3.4 错误率 (Error Rate)
衡量请求失败的比例。失败不仅包括 HTTP 5xx,还应包括业务错误码、超时、熔断等。
- 计算公式: 错误请求数 / 总请求数 × 100%
- 典型 SLO: 错误率 ≤ 0.1%
- 常见陷阱: 忽略客户端错误(4xx)中的业务异常,如“库存不足”返回 400 但实际是服务逻辑问题。
3.4 指标类型对比与选择策略
不同服务类型对指标的敏感度不同。下表总结了四类指标在不同场景下的优先级。
| 服务类型 | 首选指标 | 次选指标 | 说明 |
|---|---|---|---|
| API 网关 / 微服务 | 延迟 (P99) | 错误率 | 用户体验直接受响应速度影响 |
| 数据库 / 缓存 | 可用性 | 吞吐量 | 数据层必须持续可读写 |
| 消息队列 / 流处理 | 吞吐量 | 延迟 (P50) | 关注处理能力而非单条速度 |
| CDN / 静态资源 | 可用性 | 延迟 (P95) | 全球多节点可用性优先 |
| 批处理 / 离线任务 | 错误率 | 吞吐量 | 关注数据完整性和完成度 |
避坑指南:不要试图为每个指标都设定 SLO。一个服务通常 2~3 个 SLO 就足够。过多的 SLO 会导致错误预算碎片化,团队无法聚焦真正的用户关键路径。在服务目录中,每个服务条目应明确标注其“黄金信号”指标。
3.5 定义 SLO 的实操步骤
在服务目录中为每个服务定义 SLO 时,建议遵循以下四步流程:
- 识别用户旅程: 列出该服务对外提供的关键 API 或功能点,例如“用户登录”、“商品搜索”、“订单提交”。
- 选择黄金信号: 从延迟、可用性、错误率、吞吐量中选出 2~3 个与用户体验最相关的指标作为 SLI。
- 设定初始阈值: 基于过去 1~3 个月的历史数据,取 P99 或 P95 值作为初始 SLO 阈值。如果没有历史数据,先设定一个宽松值(如 99.9%),后续逐步收紧。
- 定义时间窗口: 决定 SLO 的评估周期。常见窗口有:滚动 30 天、滚动 7 天、日历月度。滚动窗口更适合自动化发布策略,因为它能平滑处理突发波动。
3.6 常见 SLO 定义示例(服务目录 YAML 片段)
以下是一个服务目录中 SLO 配置的 YAML 示例,展示了如何将上述概念落地为机器可读的配置。
# service-catalog/checkout-service/slo.yaml
apiVersion: catalog.slo/v1
kind: ServiceSLO
metadata:
name: checkout-service-slo
service: checkout-service
spec:
# 可用性 SLO
- name: availability
sli:
type: availability
measurement: "successful_requests / total_requests"
dataSource: prometheus
query: 'sum(rate(http_requests_total{service="checkout",status!~"5.."}[5m])) / sum(rate(http_requests_total{service="checkout"}[5m]))'
target:
threshold: 99.99
unit: percent
window: rolling_30d
errorBudget:
initial: 0.01 # 1 - 0.9999 = 0.0001 = 0.01%
# 延迟 SLO
- name: latency-p99
sli:
type: latency
percentile: 99
dataSource: prometheus
query: 'histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="checkout"}[5m])) by (le))'
target:
threshold: 200
unit: ms
window: rolling_7d
errorBudget:
initial: 0.1 # 允许 0.1% 的请求超过 200ms
自动化触发点:当 CI/CD 流水线读取到上述 SLO 配置时,会自动计算当前错误预算消耗。如果
errorBudget.remaining < 20%,流水线将阻断本次部署,并通知 SRE 团队。这个逻辑将在第 5 章“错误预算驱动的部署门禁”中详细实现。