3.1 六层金字塔总览
上一节:无 | 下一节:3.2 组件基准
一句话结论
性能测试分六层,每层回答不同的问题。 记住一条法则:要回答「为什么慢」,越往下层(越隔离)越好;要回答「能扛多少」,必须往上走(越接近真实)。
一、用汽车研发理解六层测试
汽车厂商研发一款新车,不会直接让试车员开上高速测。它会经历一整套逐级放大的测试:
| 汽车研发阶段 | 对应的性能测试 | 干什么 | 成本 |
|---|---|---|---|
| 零件台架试验 | 微基准 | 一个轴承在试验台上转到坏,测寿命 | 极低 |
| 总成试验 | 组件基准 | 发动机装在台架上跑,测功率油耗 | 低 |
| 整车转鼓试验 | 集成基准 | 整车在实验室里模拟行驶 | 中 |
| 真实道路测试 | 全链路负载 | 开上真实道路、真实天气、真实交通 | 高 |
| 碰撞试验 | 破坏性测试 | 故意撞毁,看怎么坏、能不能保命 | 高 |
| 耐久路试 | 浸泡测试 | 跑 10 万公里,看哪里先磨坏 | 很高 |
| 量产决策 | 容量测试 | 决定生产多少台、什么配置 | 很高 |
从这张表能读出三件事:
- 越往上越接近真实,也越贵。 台架试验一小时几百块,风洞试验按小时上万。
- 越往下越容易定位。 台架上的轴承坏了,你立刻知道是轴承的问题;整车上异响,你要查几十个可能。
- 每一层都有它才能发现的盲区。 台架测不出风噪,路测才能;路测测不出 10 万公里后的磨损,耐久才能。
性能测试完全一样。
二、六层详解
| 层级 | 测什么 | 时间尺度 | 单次耗时 | 能发现 | 盲区 |
|---|---|---|---|---|---|
| ① 微基准 | 单个方法/算法 | 纳秒–微秒 | 秒级 | 算法与常数优化、分配热点 | 看不到 IO、锁、GC 的真实交互 |
| ② 组件基准 | Repository、序列化、缓存 | 微秒–毫秒 | 几十秒 | SQL 慢、N+1、序列化开销、索引缺失 | 无网络、无网关、无真实并发 |
| ③ 集成基准 | 单服务完整启动 + 真实依赖 | 毫秒 | 分钟级 | 连接池、事务、启动预热、AOP 开销 | 无多服务放大效应 |
| ④ 全链路负载 | 多服务 + 网关 + 真实网络 | 毫秒–秒 | 十分钟级 | 排队、级联、限流、超时配合 | 成本高、定位难、噪声大 |
| ⑤ 专项测试 | 压力 / 尖峰 / 浸泡 | 分钟–小时 | 小时级 | 拐点、崩溃形态、资源泄漏 | 不回答「为什么」 |
| ⑥ 容量测试 | 多副本 + 负载分配 | 小时 | 小时级 | 副本数与规格决策 | 需要接近生产的拓扑 |
三、核心判断法则
法则一:诊断往下,容量往上
「这个接口为什么慢?」 → 往下走:组件基准 / 微基准 / 剖析
「这个服务能扛多少?」 → 往上走:全链路负载 / 容量测试
混用会怎样:
| 错误做法 | 后果 |
|---|---|
| 用微基准的结论推测线上容量 | 忽略了排队、GC、连接池、网络,结论严重乐观 |
| 用全链路压测来定位瓶颈 | 花几小时,只得到一个 QPS 数字 |
| 用组件基准验收 SLO | 测量点不对(不含网络与排队),SLO 形同虚设 |
法则二:每一层都有「只有它能发现」的东西
这是判断「该用哪一层」的最实用标准。问自己:这个问题在哪一层会第一次显现出来?
| 问题类型 | 第一次显现的层级 |
|---|---|
| 算法复杂度、分配热点 | ① 微基准 |
| 缺索引、N+1、序列化开销 | ② 组件基准 |
| 连接池不足、事务范围过大 | ③ 集成基准 |
| 排队、级联超时、限流配置 | ④ 全链路 |
| 内存/连接泄漏 | ⑤ 浸泡 |
| 副本数与规格 | ⑥ 容量 |
注意:很多问题在低层级就能发现,根本不需要全链路。这就是「一上来就压全链路」的最大浪费。
法则三:能用便宜层级回答的,绝不用贵的
压测环境有成本(机器、数据准备、人力、时间),而不同层级的成本差几个数量级:
微基准: 每次几十秒,几乎零成本
组件基准: 每次几十秒到几分钟,一台开发机
集成基准: 每次几分钟,需要容器/数据库
全链路: 每次几十分钟到几小时,需要完整环境和数据准备
浸泡: 数小时到数天,占着一整套环境
原则:一个「只在全链路压测里出现」的性能问题,通常不是代码慢,而是配置/拓扑/交互问题。这个判断本身就是一个重要线索。
四、一个典型的错误流程 vs 正确流程
❌ 错误流程(大多数团队的现状)
① 上线前压全链路 40 分钟
② 发现 P99 超标
③ 开会讨论「可能是数据库慢?」
④ 猜测性优化(加缓存、加索引、加机器)
⑤ 再压一次,发现变化不大
⑥ 上线,提心吊胆
问题:跳过了解析环节,优化是「猜」的。
✅ 正确流程
① 组件基准(1 分钟)→ 定位到具体 SQL:某查询 P99 = 380 ms
② 微基准 / EXPLAIN → 确认是缺索引导致全表扫描
③ 加索引,组件基准复测 → P99 降到 12 ms
④ 集成基准(5 分钟)→ 确认连接池、事务没问题
⑤ 全链路压测(30 分钟)→ 验收 SLO、确认拐点后移
⑥ 记入容量表
注意第 ⑤ 步的定位:全链路在这里的作用是验收,不是定位。这就是正确使用层级的方式。
五、本节小结
- 性能测试分六层:微基准、组件基准、集成基准、全链路负载、专项测试、容量测试。
- 诊断往下走(越隔离越容易定位),容量往上走(越接近真实越可信)。
- 判断该用哪一层的实用方法是问:「这个问题在哪一层会第一次显现?」
- 能用便宜层级回答的,绝不用贵的——一个只在全链路出现的问题,往往指向配置/拓扑而非代码。
- 全链路压测的正确定位是验收,不是定位。
六、自测
- 「接口的 P99 从 80 ms 涨到 400 ms,QPS 没变,CPU 不高」——你会从哪一层开始查?为什么不是从全链路开始?
- 一个团队只有全链路压测能力(没有组件基准)。请说出这种能力的三个具体缺陷。
- 「我要验证新版本能不能满足 SLO」和「我要知道为什么这个版本比上个版本慢」——这两个问题分别该用哪一层?
- 从组件基准或剖析开始(或直接采火焰图)。理由:① 现象是「QPS 没变、CPU 不高但延迟涨了」,典型的等待类问题(等数据库、等锁、等下游);② 这种问题在隔离环境下最容易定位——组件基准能直接告诉你「是哪条 SQL 慢了」;③ 如果先做全链路压测,这 400 ms 会被淹没在网络、网关、排队的噪声里,你可能花几小时只得到「整体慢」的结论。正确顺序:先用组件基准/火焰图定位到具体环节,再用全链路验收修复效果。
- ① 定位能力缺失:只能看到「整体慢」,无法归因到具体 SQL/序列化/锁;② 迭代太慢:每次压测几十分钟起,一天只能试 2–3 个假设,而组件基准一分钟能试一次——优化迭代速度直接决定优化质量;③ 无法做「单变量实验」:全链路里改一处,效果被其他环节的噪声掩盖,无法判断是否真的有效;④ 成本高,导致「能少测就少测」,最终变成「上线前压一次」的形式主义。
- 前者用全链路负载测试(因为 SLO 的测量点是客户端/网关,必须包含网络与排队);后者用组件基准 + 剖析(因为要知道「为什么慢」,需要隔离环境下的归因)。注意顺序:通常先用后者找出原因、改完,再用前者验收——不要用全链路来定位。