SLA/SLO/SLI 与容量规划
SRE 的核心是量化可靠性。SLA/SLO/SLI 定义了"多可靠算足够可靠",容量规划确保资源满足这些目标。
1. 定义区分
| 缩写 | 全称 | 含义 | 示例 |
|---|
| SLI | Service Level Indicator | 服务质量指标 | 请求延迟 P99 < 200ms |
| SLO | Service Level Objective | 目标值 | 99.9% 的请求延迟 < 200ms |
| SLA | Service Level Agreement | 服务等级协议(对外承诺) | 可用性 < 99.9% 退款 10% |
SLI: 测量什么
↓
SLO: 目标值多少
↓
SLA: 达不到的后果(法务/商务)
2. SLI 选择
Google SRE Book 推荐的 SLI 类型:
四类黄金信号
| 信号 | 说明 | 指标示例 |
|---|
| 延迟 | 服务响应时间 | P50/P95/P99 延迟 |
| 流量 | 请求量 | QPS、带宽 |
| 错误 | 失败率 | HTTP 5xx 比例 |
| 饱和度 | 资源利用率 | CPU > 80%、磁盘满 |
SLI 制定原则
- 用户视角:测量用户感受到的质量
- 可量化:能够用监控工具持续测量
- 可行动:触发后知道如何改进
- 不过度:选择最关键的几个(3-5 个)
3. SLO 制定方法
可用性 SLO 参考
| SLO | 年停机时间 | 适用场景 |
|---|
| 99% | 3.65 天 | 内部工具 |
| 99.9% | 8.76 小时 | 核心业务 |
| 99.99% | 52.56 分钟 | 关键支付 |
| 99.999% | 5.26 分钟 | 极少场景 |
更高 SLO ≠ 更好。SLO 提升 10 倍,成本可能提升百倍。
错误预算
错误预算 = 1 - SLO
SLO 99.9% → 年错误预算 = 0.1% × 525600 分钟 = 525.6 分钟
每月可用预算 = 525.6 ÷ 12 ≈ 43.8 分钟
用途:
- 本月已用 30 分钟 → 谨慎发布,加强测试
- 本月已用 50 分钟 → 冻结发布,聚焦稳定性改进
多层级 SLO
组织级 SLO: 99.99%(核心业务总览)
│
├─ 产品级 SLO: 99.95%(具体产品)
│ │
│ └─ 服务级 SLO: 99.9%(单个服务)
│
└─ 基础设施 SLO: 99.999%(K8s 集群)
4. 容量规划
核心公式
所需容量 = 预测峰值 × 冗余系数 × 增长余量
预测峰值: 业务高峰期的资源需求
冗余系数: N+1 或 N+2(通常 1.3-1.5)
增长余量: 未来 3-6 个月增长预期
容量模型
| 步骤 | 方法 |
|---|
| 基线测量 | 日常负载下的资源使用 |
| 峰值分析 | 历史流量峰值、周期性规律 |
| 关联建模 | QPS → CPU/内存/带宽的换算关系 |
| 压力测试 | 验证容量模型 |
扩容策略
| 策略 | 触发条件 | 优点 | 缺点 |
|---|
| 垂直扩容 | 资源使用率持续高 | 简单 | 有上限 |
| 水平扩容 | QPS 超过阈值 | 弹性强 | 数据一致性 |
| 预测扩容 | 定时/预期高峰 | 无冷启动 | 资源闲置 |
| 按需扩容 | K8s HPA | 最省成本 | 延迟敏感 |
5. 压测方法论
压测类型
┌───────────────────────────────────────────┐
│ 负载测试 (Load Testing) │
│ 目标: 验证系统在正常负载下的表现 │
│ 方法: 逐步加压至目标 QPS │
├───────────────────────────────────────────┤
│ 压力测试 (Stress Testing) │
│ 目标: 找到系统极限、观察恢复过程 │
│ 方法: 加压至系统崩溃 │
├───────────────────────────────────────────┤
│ 稳定性测试 (Soak Testing) │
│ 目标: 长时间运行发现内存/连接泄漏 │
│ 方法: 持续跑 8-24 小时 │
├───────────────────────────────────────────┤
│ 峰值测试 (Spike Testing) │
│ 目标: 突发流量应对能力 │
│ 方法: 瞬间加压数倍 │
└───────────────────────────────────────────┘
压测工具
| 工具 | 特点 | 适用 |
|---|
| JMeter | GUI 配置、插件丰富 | Web 应用 |
| k6 | 代码即脚本、云原生 | API 压测 |
| Locust | Python 编写、分布式 | 自定义场景 |
| Gatling | Scala、高性能 | 复杂协议 |
| ** vegeta** | 命令行、Go 编写 | 快速测试 |
k6 示例
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 100 }, // 逐步加压
{ duration: '5m', target: 100 }, // 稳态
{ duration: '2m', target: 200 }, // 继续加压
{ duration: '5m', target: 200 }, // 稳态
{ duration: '2m', target: 0 }, // 减压
],
thresholds: {
http_req_duration: ['p(99)<200'],
http_req_failed: ['rate<0.1'],
},
};
export default function () {
const res = http.get('https://api.example.com/orders');
check(res, {
'status is 200': (r) => r.status === 200,
});
sleep(1);
}
总结
| 维度 | 核心 |
|---|
| SLI | 测量什么 |
| SLO | 目标值(平衡可靠性与成本) |
| 错误预算 | 可靠性资源,指导发布策略 |
| 容量规划 | 资源支撑 SLO 的能力 |
| 压测 | 验证容量与极限 |
没有无限可靠性的系统,只有清晰定义"足够可靠"并为之投入的系统。
继续阅读
探索更多技术文章
浏览归档,发现更多关于系统设计、工具链和工程实践的内容。