4. 压测脚本设计
脚本设计,说白了就是让压测工具模拟出「真人」的行为。我见过太多团队,工具装好了,脚本一跑,结果全是无效数据。为什么?因为脚本太「假」了。
今天咱们就聊聊脚本设计的五个核心要素。每个我都踩过坑,希望你能绕过去。
4.1 参数化:别让所有用户都叫「张三」
你想想看,如果1000个并发用户都用同一个账号登录,那后台看到的就一个session。这能叫压测吗?这叫单用户反复刷。
参数化的本质,就是让每个虚拟用户使用不同的数据。
核心原则: 参数化数据要足够大,至少是并发数的3-5倍。我曾经遇到过参数池只有50条,并发200,结果数据被循环用了4轮,接口缓存命中率飙升,压测结果完全失真。
常见的参数化方式有几种:
- CSV数据文件:适合大批量、有规律的测试数据
- 计数器:适合生成唯一ID、订单号等
- 随机函数:适合手机号、邮箱等格式固定但内容随机的字段
- 数据库查询:从真实数据库中提取数据
// JMeter中CSV参数化的典型配置
// 文件格式:user_id,password,
// 10001,pass123,abc123
// 10002,pass456,def456
// 在请求中引用:${user_id}、${password}、${}
我的习惯: 参数化文件的第一行不要放表头。很多新手放了表头,结果第一个请求传进去的是"user_id"这个字符串,接口直接报错。排查半天才发现是这问题。
4.2 关联:把上一个请求的「回执」传给下一个
关联,说白了就是「动态传参」。比如登录后拿到,后续所有请求都要带上它。
我见过最惨的案例:某团队压测下单接口,脚本里写死了。结果压了半小时,所有订单都是同一个用户下的。运维一看,以为被攻击了,直接把账号封了。
关联的典型场景:
- 登录后获取session/
- 创建订单后获取订单ID
- 分页查询中获取下一页的游标
- 文件上传后获取文件URL
// JMeter正则表达式提取器示例
// 从响应中提取
// 响应内容:{"code":0,"data":{"":"eyJhbGciOiJIUzI1NiJ9"}}
// 正则表达式:"":"(.+?)"
// 模板:$1$
// 匹配序号:1
// 变量名:
// 后续请求引用:${}
注意: 关联提取器的作用域要设置正确。我习惯把提取器放在请求的子节点下,而不是线程组级别。这样每个请求独立提取,不会互相干扰。
4.3 断言:别让错误数据混进结果里
断言就是「检查点」。压测跑了10万次请求,你怎么知道哪些是成功的?光看HTTP状态码200是不够的。
举个例子:接口返回了200,但body里写着{"code":5001,"msg":"系统繁忙"}。这算成功吗?当然不算。
常用的断言类型:
| 断言类型 | 适用场景 | 我的建议 |
|---|---|---|
| 响应文本断言 | 检查返回内容包含特定字符串 | 最常用,比如检查"success" |
| JSON断言 | 检查JSON结构中的字段值 | 适合RESTful接口 |
| 响应时间断言 | 检查响应是否超时 | 配合性能阈值使用 |
| 大小断言 | 检查响应体大小是否在合理范围 | 防止返回空数据或异常数据 |
// JSON断言示例
// 期望:code字段等于0
// JSON Path:$.code
// 期望值:0
// 响应时间断言
// 最大响应时间:3000ms
// 超过3秒的请求标记为失败
避坑指南: 我曾经在压测一个文件上传接口时,只做了HTTP状态码断言。结果跑了2小时,发现所有请求都返回了200,但文件实际没存成功——因为磁盘满了。从那以后,我每个接口至少加一个业务断言。
4.4 思考时间:别让服务器以为你在「攻击」它
思考时间,就是模拟用户操作之间的停顿。真实用户不会像机器一样「哒哒哒」连续点击。
没有思考时间的压测,本质上是「拒绝服务攻击」。你想想看,正常人浏览网页,看一段文字至少需要几秒钟吧?
思考时间的设置原则:
- 简单操作(点击、翻页):0.5-2秒
- 中等操作(填写表单):2-5秒
- 复杂操作(支付确认、阅读条款):5-15秒
// JMeter中设置思考时间
// 使用"Constant Timer"或"Uniform Random Timer"
// 均匀随机定时器配置
// 延迟时间:3000ms(基础延迟)
// 随机范围:1000ms(额外随机延迟)
// 实际延迟:3000-4000ms之间随机
我的经验: 思考时间不是越长越好。如果设置太长,压测效率太低,跑一天也压不出几个请求。我一般先跑一轮无思考时间的压测,摸清系统上限,再加思考时间模拟真实场景。
4.5 集合点:让所有用户「同时开枪」
集合点,就是让所有虚拟用户等待,直到达到指定数量后,同时发起请求。
为什么要用集合点?因为我们要测试系统在「瞬间高并发」下的表现。比如双11秒杀、抢票、秒杀活动。
集合点的典型使用场景:
- 秒杀/抢购接口
- 登录接口(大量用户同时登录)
- 数据导出/报表生成(同时触发)
- 定时任务触发点
// JMeter集合点配置
// 使用"Synchronizing Timer"
// 配置参数
// 等待用户数:100(凑够100人一起发请求)
// 超时时间:30000ms(30秒内凑不够也发)
// 注意:超时时间不能太短,否则集合点失效
重要提醒: 集合点不要滥用。我见过有人把每个请求都加了集合点,结果压测脚本跑起来,所有用户都在等,CPU全耗在同步上了,根本没压到目标接口。集合点只加在关键路径上,一般1-2个就够了。
4.6 知识体系总览
下面这张图,帮你理清这五个要素的关系:
4.7 实战中的组合策略
光知道每个要素怎么用还不够,关键是怎么组合。我分享一个常用的脚本设计流程:
- 先搭骨架:把业务流程走通,用关联把请求串起来
- 再填血肉:把硬编码的数据替换成参数化
- 加断言:每个关键接口至少加一个业务断言
- 调节奏:根据业务场景设置合理的思考时间
- 加集合点:只在需要测试并发瓶颈的地方加
最后说一句: 脚本设计没有银弹。不同业务、不同架构,侧重点完全不同。我的建议是——先跑起来,再优化。别一开始就追求完美,压测脚本是迭代出来的。