文档目录

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、测定拐点、验证级联行为
        ↓
④ 回到 ① 继续下一轮(如果 ③ 不达标)

注意这个循环:全链路不达标 → 回到组件基准定位 → 修复 → 再回全链路验收。不要在全链路层级上反复猜。


六、本节小结

  1. 集成基准填补「单服务完整链路」的空白:事务、连接池、拦截器、启动预热。
  2. 全链路补的是「排队与跨服务放大」——它只该用于验收 SLO、测容量、验证级联。
  3. 全链路绝不能用来定位:它的数字是总账,无法反推明细。
  4. 全链路压测最常见的三个坑:拿它定位、环境与生产不一致、压测客户端与服务同机。
  5. 正确循环:组件基准定位 → 集成基准确认 → 全链路验收 → 不达标则回到组件基准。

七、自测

  1. 一个团队的全链路压测显示 P99 超标。他们的下一步是「把压测时长从 30 分钟加到 2 小时,看能不能压出更多问题」。请评价这个决定。
  2. 集成基准和全链路压测,哪个更适合验证「事务范围过大导致连接被长时间占用」?为什么?
  3. 为什么「压测客户端与服务器在同一台机器上」会同时高估和低估性能?
  1. 方向错了。延长压测时长不会让「定位」变得更容易——它只会得到更多「总账」数据。正确做法是:回到组件基准/集成基准去定位,找出 P99 的构成(哪一跳占了多少),修复后再回全链路验收。唯一值得延长时长的理由是「浸泡测试」,那是为了发现内存/连接泄漏(第 5 节),而不是为了定位瓶颈。另外可以加一句:如果想要更多信息,应该延长时长的同时采集服务端指标与火焰图,而不是单纯延长时间。
  2. 集成基准。理由:① 「事务范围过大占用连接」是单服务内部的行为,不需要多服务拓扑就能复现;② 集成基准能观察到连接池的 active/pending 与事务开启/提交的时间点,定位精确;③ 集成基准可重复性高、成本低,能快速迭代事务范围的调整。全链路压测里,这个现象会被网络与其他服务掩盖,而且每次迭代要几十分钟——用它验证「修复是否有效」可以,用它定位不行。
  3. 高估:客户端与服务在同一台机器时,网络往返被压缩到接近 0(走本地回环),所以测出的延迟比真实用户低;低估:压测客户端自己也要消耗 CPU、内存、网络和临时端口,与服务抢资源,导致服务端表现变差(延迟升高、吞吐下降)。两个方向同时存在,所以最终数字既不代表用户视角、也不代表服务真实能力——完全不可用。