1.9 Lab 1:写出你的第一份 SLO 与延迟预算
上一节:1.8 案例解剖 | 下一节:第 2 章 Kotlin/JVM 性能基础 配套代码:01-metrics-and-slo/09-lab1 预计时长:60 分钟
一、这个 Lab 的目标
把本章的理论变成两张能贴在墙上的表,以及一个被修正的埋点。
不需要你压测出数据(那是第 3–4 章的事),只需要你把「要测什么、怎么算达标」想清楚。这一步想不清楚,后面所有压测都是白压。
二、任务清单
| # | 任务 | 产出 | 时长 |
|---|---|---|---|
| 1 | 选 2 个接口,写完整 SLO 表 | docs/slo.md |
20 min |
| 2 | 为较复杂的接口写延迟预算表 | 同上文件 | 20 min |
| 3 | 找出并修正一个错误埋点 | 代码改动 + 说明 | 15 min |
| 4 | 建实验档案 | docs/experiments/E01-.../README.md |
5 min |
三、任务 1:SLO 表
接口选择建议:选一个「读多写少、调用数据库」的接口,和一个「写操作、有事务」的接口。这样能覆盖两种不同的延迟特征。
SLO 表必须包含四要素(见 1.4 节):
| 字段 | 你的填写 |
|---|---|
| 接口 | |
| 关键路径 | 客户端 → ? → ? → ? |
| 目标 QPS | (写峰值,不是平均) |
| P50 / P95 / P99 / P999 | |
| 错误率阈值 | |
| 负载前提(数据量 + 分布 + 缓存状态) | |
| 测量点 | 客户端 / 网关 / 应用内 |
| 持续时长(预热 + 稳态) | |
| 环境(实例规格、副本数) | |
| 崩溃线(压力测试终止条件) | |
| 测量日期与版本 |
自检三问(答不上来就重写):
- 别人拿着这张表,能否独立复现出同样的测试条件?
- 「负载前提」这一栏,是否写清了数据分布(均匀还是幂律)?
- 「测量点」这一栏,是否与「用户感知」对齐?
不要凭感觉填 QPS。 去问你产品的业务方,或者从现有监控里取真实峰值。如果取不到,就在表里标注「待确认」——这本身就是一个重要发现。
四、任务 2:延迟预算表
对着接口的关键路径拆每一跳:
| 环节 | 预算 (P99) | 实测 | 状态 | 备注 |
|---|---|---|---|---|
| 客户端 → 网关 | 留空 | |||
| 网关处理 | 留空 | |||
| 应用排队 | 留空 | 这一项没有代码,只能靠饱和度指标 | ||
| 应用逻辑 | 留空 | |||
| ├ 数据库 | 留空 | |||
| ├ 缓存 | 留空 | |||
| └ 下游依赖 | 留空 | |||
| 响应传输 | 留空 | |||
| 余量 | — | 必须 > 0 |
三个必须做的检查:
- 做加法:所有预算之和 + 余量 ≤ SLO 目标。超了就砍。
- 标出并行:哪些依赖是并行调用的?并行段取最大值而不是相加。
- 推导超时:为每一跳写出超时值,并确认逐层递减。
超时预算表(第二张表):
| 层 | 上游给的时间 | 本层超时 | 留给下游 |
|---|---|---|---|
| 客户端 | — | ||
| 网关 | |||
| 应用 | |||
| 数据库 | — | ||
| 缓存 | — |
实测列现在留空是故意的——第 4 章搭好观测回路后,你会回来把它填满,那时这张表就变成了你的定位工具。
五、任务 3:找出一个错误埋点
在你现在的代码里找一处测量方法错误。参考 1.8 节 的四个原因,常见的有:
| 类型 | 怎么找 |
|---|---|
| 分母错误 | 搜索计时/统计代码,看它是在 try 的哪一步记录的——异常路径是否被跳过 |
| 测量点不明确 | 看埋点是在 handler 入口还是中间件里,是否漏掉了序列化 |
| 只测了「成功」 | 看延迟指标的分母是不是「成功请求数」 |
| 缺少依赖级埋点 | 看能否回答「这个接口的 P99 里数据库占多少毫秒」 |
输出格式:
### 错误埋点:<位置>
- **现状**:<代码片段或描述>
- **问题**:<属于哪一类错误>
- **会导致的错误结论**:<例如「超时请求被剔除,P99 虚低 80%」>
- **修正方式**:<具体改法>
验收要求:这个描述要能让别人不看代码也明白错在哪。
六、任务 4:建实验档案
按 docs/experiments/_TEMPLATE/README.md 建 docs/experiments/E01-slo-baseline/,并在索引 docs/experiments/README.md 里加一行。
这次实验的「原始结果」就是你的两张表,「观察与解释」写你在填表过程中发现的不确定项(比如「峰值 QPS 未知,需向业务确认」)。
提醒:填表时发现的「填不出来」的地方,比填出来的数字更有价值。它们是第 4、5 章的输入。
七、验收标准
- SLO 表含四要素,且「负载前提」写明了数据量与数据分布。
- SLO 的测量点与「用户感知」对齐(客户端或网关),不是只看应用内。
- 延迟预算表做过加法检查,余量为正。
- 写出了超时预算,且逐层递减。
- 找到一个真实的错误埋点,并说明了它会导致什么错误结论。
- 实验档案已建立,索引已更新。
八、常见问题
Q:我拿不到真实的峰值 QPS 怎么办? A:标注「待确认」,并写上你从监控里看到的当前值。拿不到业务数据本身就是重要信息——说明你们的容量规划目前没有依据。这可以成为你向业务方提问的具体抓手。
Q:延迟预算里的「应用排队」怎么估? A:第一轮可以凭经验填(比如占总预算的 10%),然后标注「待实测」。第 4 章有了线程池队列、连接池 pending 指标后,可以用 Little’s Law 反推真实值。
Q:我现在的项目没有埋点,怎么办? A:那就把任务 3 改成「设计埋点方案」:确定要埋哪些指标、在每个测量点各埋什么、用什么工具。这正是第 4 章的内容,提前做一遍会成为你的主线。
Q:SLO 数值怎么定? A:先问业务方三个问题:「如果这个操作要等 500 ms / 1 s / 2 s,用户会怎样?」从回答里找到「明显流失」的临界点,SLO 设在它稍前面。不要从「技术上能压到多快」倒推,那会导致成本和告警噪声失控。