3.3 集成基准与全链路:什么时候值得
上一节:3.2 组件基准 | 下一节:3.4 负载曲线 配套代码:03-test-pyramid/03-integration-and-e2e
一句话结论
集成基准补的是「单服务完整启动」这一层;全链路压测补的是「排队与跨服务放大」。 全链路很贵,只该用在验收 SLO、测容量、验证级联行为这三件事上——绝不能用来定位瓶颈。
一、用「转鼓试验」和「真实路试」理解这两层
| 转鼓试验(集成基准) | 真实路试(全链路) | |
|---|---|---|
| 在哪跑 | 实验室,整车在转鼓上 | 真实道路 |
| 有什么 | 真车、真发动机、真轮胎 | 加上真实天气、交通、坡度、油品 |
| 能发现 | 整车级别的匹配问题(变速箱逻辑、散热) | 高速风噪、长上坡过热、堵车时的油耗 |
| 成本 | 中 | 高 |
| 可重复性 | 高(环境可控) | 低(天气、交通不可控) |
对应到后端:
| 集成基准 | 全链路负载 | |
|---|---|---|
| 范围 | 单服务完整启动 + 真实依赖 | 多服务 + 网关 + 真实网络 |
| 能发现 | 连接池、事务边界、AOP/拦截器开销、启动预热、序列化链路 | 排队、级联超时、限流配置、跨服务放大 |
| 成本 | 分钟级 | 十分钟到小时级 |
| 可重复性 | 高 | 中(受环境噪声影响大) |
二、集成基准:填补「单服务完整」的空白
组件基准只测一个 Repository 或一个方法。但真实请求还会经过:
HTTP 层 → 拦截器/中间件 → 鉴权 → 参数校验 → 业务逻辑 → 事务 → 多个 Repository → 序列化 → 响应
这些环节的成本(拦截器链、事务开启/提交、日志、指标埋点)只有把服务完整启动起来才能测到。
集成基准该测的四件事:
| 测什么 | 为什么 |
|---|---|
| 端到端 handler 耗时 | 完整的一次请求处理(不含网络) |
| 事务开销 | 事务范围是否过大?有没有不必要的 @Transactional? |
| 连接池行为 | 并发下连接够不够?pending 是否 > 0? |
| 启动预热曲线 | 从启动到稳态要多久?(第 2 章 2.4 节的冷启动) |
实现要点:
- 用 Ktor 的
testApplication或直接启动真实端口(后者更接近真实)。 - 不加反向代理——这一层的目的是「单服务完整」,不是「全链路」。
- 一定要先预热再测量(JIT + 连接池 + 缓存)。
- 并发模型要明确:闭环(方便对比)还是开环(接近真实)。
⚠️ 集成基准用闭环模型测尾延迟会低估(第 0 章 0.6 节)。它的定位是「与组件基准做相对比较」,不是「验收 SLO」。
三、全链路:三个值得做的理由,三个不值得的
✅ 值得做
| 理由 | 说明 |
|---|---|
| ① 验收 SLO | SLO 的测量点是客户端/网关,必须包含网络与排队(第 1 章 1.3 节) |
| ② 找拐点与容量 | 单实例在隔离环境下测出的拐点,不等于真实拓扑下的容量 |
| ③ 验证级联与配置 | 超时链是否递减、限流阈值是否合理、重试是否放大——这些只在多服务交互时暴露 |
❌ 不值得做
| 理由 | 说明 |
|---|---|
| ① 算法选型 | 用微基准或组件基准,快 100 倍 |
| ② 单点代码优化 | 用剖析定位,用组件基准验证 |
| ③ 没有独立压测环境 | 在生产或开发机上压,数据不可用(第 1 章 1.7 节的环境清单) |
判断方法:问自己「这个问题在单服务隔离环境下能测出来吗?」如果能,就不要用全链路。
四、全链路压测最容易踩的三个坑
❶ 用它来「定位」
❌ 「压了 40 分钟,P99 是 420 ms,我们查查是哪里慢吧。」
问题:全链路的数字是总账,里面混着网络、网关、排队、应用、依赖。你无法从总账反推出明细。
正确姿势:全链路只回答「达标 / 不达标」「拐点在哪」。不达标时,回到低层级去定位。
❷ 压测环境与生产不一致
第 1 章 1.7 节的九项清单在这一层最重要。最常见的三个不一致:
| 不一致项 | 后果 |
|---|---|
| 容器 CPU limit | 生产被节流,压测环境无限制 → 数据完全不可迁移 |
| 数据量与分布 | 执行计划不同、缓存命中率不同 |
| 副本数与拓扑 | 单实例压测测不出负载分配与跨实例争用 |
❸ 忽略「客户端到网关」这一段
很多团队的全链路压测实际上是「压测客户端 → 网关 → 服务」,但压测客户端与服务在同一机房甚至同一台机器。这会导致:
- 网络延迟被严重低估(真实用户可能在另一个城市)
- 压测机抢 CPU
至少要做到:压测客户端独立机器;更好的是跨可用区压测。
五、三层协同的正确姿势
① 组件基准(分钟级)
└─ 定位到具体 SQL / 序列化 / 映射问题
↓
② 集成基准(分钟级)
└─ 确认单服务完整链路没问题(连接池、事务、拦截器)
↓
③ 全链路压测(小时级)
└─ 验收 SLO、测定拐点、验证级联行为
↓
④ 回到 ① 继续下一轮(如果 ③ 不达标)
注意这个循环:全链路不达标 → 回到组件基准定位 → 修复 → 再回全链路验收。不要在全链路层级上反复猜。
六、本节小结
- 集成基准填补「单服务完整链路」的空白:事务、连接池、拦截器、启动预热。
- 全链路补的是「排队与跨服务放大」——它只该用于验收 SLO、测容量、验证级联。
- 全链路绝不能用来定位:它的数字是总账,无法反推明细。
- 全链路压测最常见的三个坑:拿它定位、环境与生产不一致、压测客户端与服务同机。
- 正确循环:组件基准定位 → 集成基准确认 → 全链路验收 → 不达标则回到组件基准。
七、自测
- 一个团队的全链路压测显示 P99 超标。他们的下一步是「把压测时长从 30 分钟加到 2 小时,看能不能压出更多问题」。请评价这个决定。
- 集成基准和全链路压测,哪个更适合验证「事务范围过大导致连接被长时间占用」?为什么?
- 为什么「压测客户端与服务器在同一台机器上」会同时高估和低估性能?
- 方向错了。延长压测时长不会让「定位」变得更容易——它只会得到更多「总账」数据。正确做法是:回到组件基准/集成基准去定位,找出 P99 的构成(哪一跳占了多少),修复后再回全链路验收。唯一值得延长时长的理由是「浸泡测试」,那是为了发现内存/连接泄漏(第 5 节),而不是为了定位瓶颈。另外可以加一句:如果想要更多信息,应该延长时长的同时采集服务端指标与火焰图,而不是单纯延长时间。
- 集成基准。理由:① 「事务范围过大占用连接」是单服务内部的行为,不需要多服务拓扑就能复现;② 集成基准能观察到连接池的
active/pending与事务开启/提交的时间点,定位精确;③ 集成基准可重复性高、成本低,能快速迭代事务范围的调整。全链路压测里,这个现象会被网络与其他服务掩盖,而且每次迭代要几十分钟——用它验证「修复是否有效」可以,用它定位不行。 - 高估:客户端与服务在同一台机器时,网络往返被压缩到接近 0(走本地回环),所以测出的延迟比真实用户低;低估:压测客户端自己也要消耗 CPU、内存、网络和临时端口,与服务抢资源,导致服务端表现变差(延迟升高、吞吐下降)。两个方向同时存在,所以最终数字既不代表用户视角、也不代表服务真实能力——完全不可用。