性能测试:如何设计一套业务压测方案

写压测方案时,文档内容看起来很完整:

  • 时间
  • 人员
  • 环境
  • 工具
  • 并发数

但真正执行时,往往还是会乱。
因为这种方案更像“安排表”,不是“验证设计”。

从真实项目落地看,一套有价值的业务压测方案,至少要回答清楚下面这些问题:

  • 这次压测到底是为了解决什么决策问题
  • 业务流量模型长什么样
  • 压测会波及哪些系统和依赖
  • 成功、失败、停止的边界分别是什么
  • 最终输出要给谁看、支持什么决策

如果这些问题没先想清楚,执行越努力,最后越容易得到一堆热闹但不太能用的数据。

一、压测方案首先是“问题定义文档”,不是“执行清单”

通常不会一上来先写:

  • 并发多少
  • 压多久
  • 用什么工具

因为这些都属于后置选择。
更前面的事情是先定义问题。

比如这次压测到底是为了回答哪类问题:

  • 上线前,当前容量是不是够
  • 大促前,峰值流量是不是有风险
  • 架构改造后,瓶颈有没有迁移
  • 新链路接入后,会不会把老系统拖慢

不同问题,对应的压测方案完全不同。

如果问题定义不清楚,后面很容易出现一种情况:

  • 压测做了
  • 报告也出了
  • 但开评审会时没人能说清楚,这次到底验证成功没有

二、业务压测方案最核心的部分,不是接口列表,而是流量模型

很多压测方案最大的薄弱点,就是业务建模太浅。

它们通常会写:

  • 压接口 A
  • 压接口 B
  • 压接口 C

但这不等于业务模型。

真正接近业务的流量模型,至少要回答这些事:

1. 用户从哪里进来

例如:

  • 首页
  • 搜索
  • 详情
  • 提交

不同入口会带来完全不同的后续链路组合。

2. 各类请求的比例是什么

如果真实业务里:

  • 查询类 70%
  • 提交类 20%
  • 支付类 10%

那你的压测就不能把三类请求平均混打,然后还试图得出真实业务结论。

3. 峰值的形成方式是什么

有些业务峰值是突然冲上去的,有些则是缓慢爬升。
这两种情况对系统的冲击方式完全不同。

例如:

  • 秒杀更像瞬时冲击
  • 日常高峰更像持续爬坡

4. 数据冷热分布是什么

如果方案里没有冷热数据概念,通常会出现两种失真:

  • 全热数据,把缓存效果夸大
  • 全冷数据,把数据库压力夸大

这两种都不接近真实生产。

三、业务压测方案里,需要把“依赖边界”写清楚

很多压测最后出问题,不是主系统自己先挂,而是依赖先出问题。
所以方案里不能只看被测系统本体,还要把依赖边界提前画出来。

至少要列清楚:

  • 哪些下游服务会被同时打到
  • 哪些第三方接口会不会被真实调用
  • 哪些缓存、中间件、数据库会被共享影响
  • 哪些系统只是读流量受影响,哪些会被写流量污染

如果这些边界不写清楚,执行时最容易出现两类事故:

  • 压测流量误伤旁路系统
  • 报告只盯主系统,却漏掉真正先出风险的依赖

四、更倾向怎么写一套真正可执行的业务压测方案

如果要写,通常会把方案至少拆成下面几块。

1. 测试目标

这里不能只写“验证性能”,要写得具体一点,比如:

  • 验证当前搜索链路是否能支撑双十一活动峰值的 1.5 倍
  • 验证架构改造后,提交链路 P99 是否明显收敛
  • 验证长稳压 2 小时后系统是否出现资源泄漏

2. 场景建模

包括:

  • 用户入口
  • 业务步骤
  • 请求比例
  • 数据准备方式
  • 并发爬坡方式

3. 指标口径

至少要提前定义:

  • TPS / QPS
  • P95 / P99
  • 错误率
  • 线程池 / 连接池
  • CPU / 内存 / 磁盘 / 网络
  • 中间件关键指标

如果不提前定口径,执行时每个人都会各看各的图。

4. 风险与停机线

例如:

  • 错误率超过多少立即停
  • 关键数据库 CPU 持续多少以上暂停加压
  • 核心依赖出现堆积后是否立即止损

5. 预期产出

也就是这次压测最后要给出什么层面的结论:

  • 能不能上线
  • 要不要扩容
  • 哪一层最该优先优化
  • 大促前还有哪些风险没消完

五、压测方案里最容易漏掉的,其实是“执行中的观察与调整策略”

很多方案写得很静态,仿佛压测只要按按钮执行就结束。
但真实场景里,执行过程本身也需要策略。

通常会提前设计:

1. 分阶段升压

而不是一次到顶。
原因很简单:

  • 便于及时发现异常
  • 便于确认瓶颈开始出现的具体拐点
  • 降低误伤环境的风险

2. 每阶段要看哪些信号

例如:

  • 吞吐有没有继续增长
  • 尾延迟是否开始劣化
  • 错误率是不是开始抬头
  • 哪个依赖的资源最先顶住

3. 什么情况下继续、暂停、回退

如果这一步不预定义,现场一出问题就会开始争论:

  • 要不要继续压
  • 这是不是正常波动
  • 现在停是不是太保守

这类争论一多,压测节奏很容易失控。

六、在项目里踩过的几个典型方案坑

坑 1:目标写得太泛,最后谁都能解释

例如只写:

  • 验证系统性能

这类目标几乎没法评价是否达成。
最后报告无论好坏,都会被不同角色按各自关注点使用。

坑 2:流量模型只按接口写,不按业务写

看起来覆盖了很多接口,实际上完全没形成真实业务链路。
这种方案最后很难回答“真实用户场景下会不会出问题”。

坑 3:没把依赖边界写清楚,压测时误伤别人

这是非常现实的问题。
尤其在共享预发环境、共享中间件环境里,如果方案没写清楚边界,压测很容易变成“连带事故”。

坑 4:监控方案缺位,报告只能靠 JMeter 图表拼

这种结果通常最尴尬:

  • 现象看到了
  • 但瓶颈说不清

最终谁都知道“有问题”,但不知道“问题在哪一层”。

七、排查压测方案本身是否靠谱时,通常先看什么

1. 先看目标是不是具体

如果目标模糊,后面方案大概率也会虚。

2. 再看流量模型是不是接近真实

特别看:

八、一个更接近真实项目的业务压测方案骨架

如果要落文档,通常不会只写段落说明,而会直接写成能执行的骨架。

例如:

模块 示例内容
测试目标 验证搜索和下单链路在活动峰值 1.5 倍下是否仍可控
核心场景 搜索 55%、详情 25%、下单 15%、支付查询 5%
数据准备 5000 用户、2 万商品、热数据占比 30%
执行阶段 100/200/300/400 并发分阶段执行
观察指标 TPS、P95、P99、错误率、数据库连接池、Redis 命中率
停机线 错误率持续 3 分钟超过 1%,或订单主库 CPU 持续超过 85%
输出结论 健康区、风险区、主瓶颈、上线建议

这种骨架的好处是,执行、观察和报告三件事天然串在一起。

九、在项目里会怎样把业务流量翻译成压测脚本

业务方案最容易空的地方,是“看起来写了场景,实际上还没落到执行粒度”。

更常用的做法是把业务动作先拆成事务:

1
2
3
4
5
事务 1:登录
事务 2:搜索
事务 3:查看详情
事务 4:提交订单
事务 5:查询订单结果

然后再给每个事务补三个实践字段:

  • 是否必须串行
  • 是否需要真实关联数据
  • 是否会产生写副作用

这样做以后,脚本设计会清楚很多。
例如:

  • 搜索和详情可以混合放量
  • 下单和支付查询必须保留强关联
  • 写链路必须单独准备可回收数据

十、压测当天怎么执行这套方案

真正执行时,通常会把节奏收得很细,而不是一份方案写完就直接开跑。

一个常用节奏是:

  1. 先做 10 分钟低压探测,确认链路、数据、监控都正常
  2. 再按阶段升压,每阶段结束做一次现场记录
  3. 每次升压前先确认上一阶段的异常是否已经解释清楚
  4. 一旦命中停机线,立即冻结当前阶段并保留证据

现场记录通常至少保留:

  • 当前执行参数
  • 本阶段关键指标摘要
  • 异常开始时间
  • 初步怀疑的瓶颈层
  • 是否继续下一阶段的决策

这样后面写报告时,不会只剩截图,没有过程。

  • 读写比例
  • 链路组合
  • 数据冷热

3. 再看监控和风险线是不是提前定义了

没有这两块,执行阶段很容易临场失控。

4. 最后才看脚本和工具细节

因为脚本写得再漂亮,如果建模方向错了,结果依然没有决策价值。

结语

一套真正有价值的业务压测方案,核心从来不是把并发数填进去,而是把“为什么测、怎么测、看到什么算正常、看到什么必须停、最后结论要支持什么决策”全部提前设计清楚。

如果这些关键问题没有回答,方案就只是执行安排;
只有把目标、模型、依赖、监控、风险和产出全部写实,压测方案才真正有工程价值。