性能测试:如何设计一套业务压测方案
写压测方案时,文档内容看起来很完整:
- 时间
- 人员
- 环境
- 工具
- 并发数
但真正执行时,往往还是会乱。
因为这种方案更像“安排表”,不是“验证设计”。
从真实项目落地看,一套有价值的业务压测方案,至少要回答清楚下面这些问题:
- 这次压测到底是为了解决什么决策问题
- 业务流量模型长什么样
- 压测会波及哪些系统和依赖
- 成功、失败、停止的边界分别是什么
- 最终输出要给谁看、支持什么决策
如果这些问题没先想清楚,执行越努力,最后越容易得到一堆热闹但不太能用的数据。
一、压测方案首先是“问题定义文档”,不是“执行清单”
通常不会一上来先写:
- 并发多少
- 压多久
- 用什么工具
因为这些都属于后置选择。
更前面的事情是先定义问题。
比如这次压测到底是为了回答哪类问题:
- 上线前,当前容量是不是够
- 大促前,峰值流量是不是有风险
- 架构改造后,瓶颈有没有迁移
- 新链路接入后,会不会把老系统拖慢
不同问题,对应的压测方案完全不同。
如果问题定义不清楚,后面很容易出现一种情况:
- 压测做了
- 报告也出了
- 但开评审会时没人能说清楚,这次到底验证成功没有
二、业务压测方案最核心的部分,不是接口列表,而是流量模型
很多压测方案最大的薄弱点,就是业务建模太浅。
它们通常会写:
- 压接口 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 | 事务 1:登录 |
然后再给每个事务补三个实践字段:
- 是否必须串行
- 是否需要真实关联数据
- 是否会产生写副作用
这样做以后,脚本设计会清楚很多。
例如:
- 搜索和详情可以混合放量
- 下单和支付查询必须保留强关联
- 写链路必须单独准备可回收数据
十、压测当天怎么执行这套方案
真正执行时,通常会把节奏收得很细,而不是一份方案写完就直接开跑。
一个常用节奏是:
- 先做 10 分钟低压探测,确认链路、数据、监控都正常
- 再按阶段升压,每阶段结束做一次现场记录
- 每次升压前先确认上一阶段的异常是否已经解释清楚
- 一旦命中停机线,立即冻结当前阶段并保留证据
现场记录通常至少保留:
- 当前执行参数
- 本阶段关键指标摘要
- 异常开始时间
- 初步怀疑的瓶颈层
- 是否继续下一阶段的决策
这样后面写报告时,不会只剩截图,没有过程。
- 读写比例
- 链路组合
- 数据冷热
3. 再看监控和风险线是不是提前定义了
没有这两块,执行阶段很容易临场失控。
4. 最后才看脚本和工具细节
因为脚本写得再漂亮,如果建模方向错了,结果依然没有决策价值。
结语
一套真正有价值的业务压测方案,核心从来不是把并发数填进去,而是把“为什么测、怎么测、看到什么算正常、看到什么必须停、最后结论要支持什么决策”全部提前设计清楚。
如果这些关键问题没有回答,方案就只是执行安排;
只有把目标、模型、依赖、监控、风险和产出全部写实,压测方案才真正有工程价值。