本文目录导读:

在PHP项目中进行压测时,串联多接口模拟真实业务流(如用户登录->浏览商品->加入购物车->下单支付)比单接口压测更有价值,以下是几种主流的实现方案,按自动化程度和复杂度排序:
使用 JMeter 的“逻辑控制器”串联(推荐)
适用场景:无代码经验、需要可视化配置、快速出报告。
核心步骤
- 线程组:设置并发用户数、Ramp-Up时间、循环次数。
- HTTP Cookie管理器:自动保存登录后返回的 Cookie,用于后续接口。
- 接口请求:按顺序添加各接口的采样器。
- 正则表达式提取器 / JSON提取器:从上一个接口的响应中提取需要的数据(例如订单ID、token)。
- 断言:验证返回是否正确。
示例流程(登录 -> 下单)
Thread Group: 10用户, 循环5次
├─ HTTP Cookie 管理器
├─ HTTP 请求: POST /api/login (传入账号密码)
│ └─ JSON提取器: 提取 $.data.token (保存为 ${token})
├─ 调试采样器(可选): 输出token验证
├─ HTTP 请求: POST /api/order (Header: Authorization: Bearer ${token})
│ └─ 参数: product_id=1&quantity=2
│ └─ JSON提取器: 提取 $.data.order_id (保存为 ${order_id})
├─ HTTP 请求: POST /api/pay (参数: order_id=${order_id})
└─ 查看结果树 / 聚合报告
关键技巧
- 参数化:用户数据从CSV文件读取,避免重复使用相同账号造成业务冲突。
- 定时器:在接口之间添加“常数吞吐量定时器”模拟用户思考时间。
使用 Locust 编写 Python 脚本(灵活可控)
适用场景:需要动态逻辑、条件分支、复杂断言、长期维护的压测项目。
示例脚本
from locust import HttpUser, task, between
class BusinessFlowUser(HttpUser):
wait_time = between(1, 3) # 用户思考时间
def on_start(self):
"""每个用户开始时的操作:登录并保存token"""
with self.client.post("/api/login", json={
"username": self.username,
"password": "123456"
}, catch_response=True) as resp:
if resp.status_code == 200:
self.token = resp.json()["data"]["token"]
resp.success()
else:
resp.failure("Login failed")
self.product_id = self.get_random_product()
def get_random_product(self):
# 从产品列表获取一个有效ID
resp = self.client.get("/api/products?limit=100")
return random.choice(resp.json()["data"])["id"]
@task(3) # 权重:该任务执行概率
def browse_and_add_cart(self):
headers = {"Authorization": f"Bearer {self.token}"}
# 浏览商品
self.client.get(f"/api/product/{self.product_id}", headers=headers)
# 加入购物车
self.client.post("/api/cart/add", json={
"product_id": self.product_id,
"quantity": random.randint(1,5)
}, headers=headers)
@task(1)
def checkout_and_pay(self):
# 创建订单
resp = self.client.post("/api/order", json={
"product_ids": [self.product_id]
}, headers={"Authorization": f"Bearer {self.token}"})
if resp.status_code == 200:
order_id = resp.json()["data"]["order_id"]
# 支付
self.client.post("/api/pay", json={
"order_id": order_id,
"payment_method": "balance"
}, headers={"Authorization": f"Bearer {self.token}"})
运行方式
locust -f flow_test.py --host=https://api.yourapp.com
使用自研脚本 + 并发库(极致定制)
适用场景:需要精确控制并发时序、与PHP项目代码交互(如直接调用框架函数)。
示例:PHP + Swoole 实现压测脚本
<?php
use Swoole\Coroutine\Http\Client;
// 参数配置
$concurrency = 20;
$users = loadUsersFromCSV('users.csv');
go(function () use ($concurrency, $users) {
$wg = new \Swoole\Coroutine\WaitGroup();
foreach ($users as $user) {
$wg->add();
go(function () use ($user, $wg) {
$client = new Client('api.yourapp.com', 443, true);
// 1. 登录
$client->post('/api/login', ['username' => $user[0], 'password' => $user[1]]);
if ($client->statusCode !== 200) return;
$token = json_decode($client->body)->data->token;
// 自动化添加鉴权头
$client->setHeaders(['Authorization' => "Bearer $token"]);
// 2. 获取随机商品
$client->get('/api/product/random');
$productId = json_decode($client->body)->id;
// 3. 加入购物车
$client->post('/api/cart/add', ['product_id' => $productId, 'quantity' => 2]);
// 4. 模拟用户思考(0.5-2秒)
\Swoole\Coroutine::sleep(mt_rand(5, 20) * 0.1);
// 5. 下单支付
$client->post('/api/checkout', ['address_id' => 1]);
$orderId = json_decode($client->body)->order_id;
$client->post('/api/pay', ['order_id' => $orderId, 'method' => 'wechat']);
// 记录结果
$client->close();
$wg->done();
});
}
$wg->wait();
});
关键设计原则
状态依赖性处理
- 无状态接口(如商品列表):直接并发调用。
- 有状态接口(需登录、需前置返回值):必须串联,但注意:
- 失败重试:如果登录失败,不再继续后续接口。
- 超时排队:使用队列管理“已登录”的token池。
避免业务冲突
- 数据隔离:压测数据使用独立测试库,或用唯一标识(
test_用户_时间戳)。 - 幂等处理:接口支持幂等(订单号带UUID),避免重复下单。
数据参数化
用户信息 CSV 文件格式:
username,password,product_id
test1,123456,101
test2,123456,102
实战建议
- 先做单接口压测:定位瓶颈后再压测串联流程。
- 减少单次流程的数据依赖:将“获取商品列表”改为“使用预设商品ID”,避免接口返回为空时流程中断。
- 监控中间状态:在聚合报告中关注“登录成功率”、“下单成功率”、“支付成功率”,而不是只看整体TPS。
- 不要遗漏清理:压测结束后,需要清理测试产生的订单、优惠券等垃圾数据。
选型矩阵
| 方案 | 复杂流程 | 动态数据 | 并发控制 | 学习成本 | 报告可视化 |
|---|---|---|---|---|---|
| JMeter | 中等 | 需插件 | 强 | 低 | 强 |
| Locust | 强 | 强 | 强 | 中 | 中 |
| 自研脚本 | 最强 | 最强 | 强 | 高 | 低 |
推荐:如果团队没有交大的压测框架技术栈,从 JMeter + JSON提取器 开始最快,需要编写复杂业务逻辑(如随机跳转、条件分支)时,切换至 Locust。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播