支付系统C扫B全链路压测方案
使用JMeter模拟真实用户的支付行为,需结合参数化、关联接口、动态数据提取、逻辑控制等关键步骤。以下是详细操作指南:
1. 创建线程组(模拟并发用户)
- 配置线程组参数:
- 线程数(Users):模拟的并发用户数(如1000)。
- Ramp-Up时间(秒):逐步启动线程的时间(如60秒内启动1000用户)。
- 循环次数:压测持续时间或循环次数。
2. 参数化支付请求数据
-
使用CSV文件存储动态数据:
- 创建CSV文件(如
payment_data.csv
),包含动态字段:user_id,amount,product_id user_001,10.00,1001 user_002,20.50,1002 ...
- 添加CSV Data Set Config:
- 文件名:
payment_data.csv
- 变量名称:
user_id,amount,product_id
- 设置循环策略(如
Recycle on EOF
)。
- 文件名:
- 创建CSV文件(如
-
随机生成数据:
- 使用JMeter函数生成随机值:
${__Random(1,1000,user_id)} # 生成1~1000的随机用户ID ${__Random(10,500,amount)} # 生成10~500的随机金额
- 使用JMeter函数生成随机值:
3. 模拟生成二维码接口
-
添加HTTP请求:
- 名称:
生成二维码
- 方法:
POST
- URL:
http://api.pay-system.com/qrcode/create
- Body参数:
{ "user_id": "${user_id}", "amount": "${amount}", "product_id": "${product_id}" }
- 名称:
-
提取动态二维码/订单ID:
- 添加正则表达式提取器或JSON提取器:
# 示例响应:{"code": 200, "data": {"order_id": "202310010001", "qrcode_url": "http://..."}} - 变量名:order_id - 正则表达式(JSON Path):`$.data.order_id`
- 添加正则表达式提取器或JSON提取器:
4. 模拟用户扫码支付
-
添加HTTP请求:
- 名称:
提交支付
- 方法:
POST
- URL:
http://api.pay-system.com/payment/submit
- Body参数:
{ "order_id": "${order_id}", "user_id": "${user_id}", "payment_type": "wechat" }
- 名称:
-
处理支付渠道Mock响应:
- 使用Response Assertion验证返回状态码(如200)。
- 提取支付渠道返回的
transaction_id
(若需要)。
5. 模拟轮询支付结果
-
添加While Controller(轮询直到支付完成):
- 条件:
${__javaScript("${payment_status}" != "success" && ${counter} < 5)}
- 计数器(Counter):
- 名称:
counter
- 从1开始,递增1,最大值5(防止无限循环)。
- 名称:
- 条件:
-
添加HTTP请求(查询结果):
- 名称:
查询支付结果
- 方法:
GET
- URL:
http://api.pay-system.com/payment/query?order_id=${order_id}
- 名称:
-
提取支付状态:
- 使用JSON提取器提取
payment_status
:- 变量名:payment_status - JSON Path:`$.data.status`
- 使用JSON提取器提取
6. 模拟异步通知回调
-
方案1:使用JSR223 Sampler模拟回调:
- 添加JSR223 Sampler(Groovy脚本):
import org.apache.http.client.methods.HttpPost import org.apache.http.entity.StringEntity import org.apache.http.impl.client.HttpClients // 创建HTTP客户端 def httpClient = HttpClients.createDefault() def httpPost = new HttpPost("http://api.pay-system.com/payment/callback") // 设置回调参数 def jsonBody = """ { "order_id": "${vars.get("order_id")}", "status": "success" } """ httpPost.setEntity(new StringEntity(jsonBody)) httpPost.setHeader("Content-Type", "application/json") // 发送回调请求 def response = httpClient.execute(httpPost) log.info("Callback response: " + response.getStatusLine().getStatusCode())
- 添加JSR223 Sampler(Groovy脚本):
-
方案2:使用HTTP请求模拟回调:
- 添加HTTP请求:
- URL:
http://api.pay-system.com/payment/callback
- Body参数:
{ "order_id": "${order_id}", "status": "success" }
- URL:
- 添加HTTP请求:
7. 添加逻辑控制与断言
-
条件逻辑(支付成功/失败):
- 使用If Controller:
- 条件:
${payment_status} == "success"
- 内部添加支付成功后的逻辑(如记录日志)。
- 条件:
- 使用If Controller:
-
响应断言:
- 验证接口返回的关键字段:
- 验证支付接口返回的"code": 200 - 验证查询结果中的"status": "success"
- 验证接口返回的关键字段:
8. 配置分布式压测(可选)
- 多机负载生成:
- 在多个机器上启动JMeter Agent(修改
jmeter.properties
中的server.rmi.ssl.disable=true
)。 - 主控机通过命令行启动压测:
jmeter -n -t payment_test.jmx -R 192.168.1.101,192.168.1.102 -l result.jtl
- 在多个机器上启动JMeter Agent(修改
9. 结果分析与调试
-
查看结果树与聚合报告:
- 使用View Results Tree调试请求/响应。
- 使用Aggregate Report分析TPS、响应时间、错误率。
-
生成HTML报告:
jmeter -g result.jtl -o report_folder
10. 示例脚本结构
Test Plan
└─ Thread Group (1000 users, 60s ramp-up)
├─ CSV Data Set Config (payment_data.csv)
├─ HTTP Request: 生成二维码
│ ├─ JSON Extractor (order_id)
├─ HTTP Request: 提交支付
├─ While Controller (轮询支付结果)
│ ├─ Counter (最大重试5次)
│ ├─ HTTP Request: 查询支付结果
│ │ ├─ JSON Extractor (payment_status)
├─ If Controller (支付成功)
│ ├─ JSR223 Sampler: 模拟异步回调
├─ Response Assertion (验证状态码)
关键注意事项
- 动态关联:确保
order_id
在接口间正确传递。 - 超时与重试:合理设置HTTP请求超时(如10秒)。
- 资源监控:结合JMeter Plugins监控服务器资源(如PerfMon插件)。
- 数据清理:压测后清理测试订单,避免影响后续测试。
通过以上步骤,可真实模拟用户从发起支付到完成的全流程行为,并验证系统在高并发下的性能瓶颈。