在 k6 性能测试工具中,场景(Scenarios) 是一个核心概念,它允许您定义不同的负载模式和测试策略,模拟真实世界中的各种用户行为模式。
什么是场景?
场景是 k6 中用于定义和组织不同负载测试策略的高级结构。每个场景可以有自己的:
虚拟用户(VU)数量
执行策略(执行器)
持续时间或迭代次数
启动时间
特定的测试逻辑
场景的核心特性
1. 独立负载配置
每个场景可以有不同的负载配置:
scenarios: {
spike_test: {
executor: 'ramping-vus',
stages: [
{ duration: '10s', target: 100 }, // 10秒内增加到100 VU
{ duration: '1m', target: 100 }, // 保持100 VU 1分钟
{ duration: '10s', target: 0 } // 10秒内降为0 VU
]
},
stability_test: {
executor: 'constant-vus',
vus: 50,
duration: '1h'
}
}
2. 多种执行器(Executors)
k6 提供多种执行器来模拟不同负载模式:
执行器类型 | 描述 | 适用场景 |
---|---|---|
shared-iterations |
所有 VU 共享总迭代次数 | 登录、注册等固定操作 |
per-vu-iterations |
每个 VU 执行固定次数的迭代 | 购物流程、搜索流程 |
constant-vus |
固定数量的 VU 运行指定时间 | 稳定性测试 |
ramping-vus |
VU 数量随时间线性增减 | 压力测试 |
constant-arrival-rate |
恒定速率生成 VU | API 负载测试 |
ramping-arrival-rate |
变化速率生成 VU | 渐变负载测试 |
3. 并行或顺序执行
多个场景可以并行或顺序执行:
scenarios: { login_scenario: { executor: 'shared-iterations', iterations: 100, vus: 20, exec: 'loginFlow' }, search_scenario: { executor: 'constant-vus', vus: 30, duration: '5m', exec: 'searchFlow', startTime: '2m' // 在登录场景开始2分钟后启动 } }
注意:如果没有参数startTime,那么默认所有场景同时启动,我们可以通过设置startTime的开始时间值,来控制不同场景的启动时间
4. 独立的指标收集
k6 会为每个场景单独收集和报告指标:
http_req_duration...........: avg=123.45ms (scenario=login_scenario) http_req_duration...........: avg=234.56ms (scenario=search_scenario) iterations..................: 100 (scenario=login_scenario) iterations..................: 1500 (scenario=search_scenario)
为什么需要场景?
模拟真实用户行为:
不同用户群体可能有不同行为模式
例如:普通用户 vs VIP 用户,浏览用户 vs 购买用户
测试系统在不同负载下的表现:
突发流量(秒杀活动)
持续负载(日常访问)
逐渐增加的负载(促销预热)
隔离测试不同功能模块:
登录模块
搜索模块
支付模块
优化测试资源使用:
并行执行多个测试场景
针对不同模块设置不同负载
场景最佳实践
1. 为关键业务流程创建独立场景
scenarios: {
user_registration: {
executor: 'per-vu-iterations',
vus: 10,
iterations: 5,
exec: 'registrationFlow'
},
product_purchase: {
executor: 'constant-arrival-rate',
rate: 30,
timeUnit: '1s',
duration: '10m',
preAllocatedVUs: 10,
exec: 'purchaseFlow'
}
}
2. 使用混合负载模式
scenarios: {
// 正常负载
normal_traffic: {
executor: 'constant-vus',
vus: 100,
duration: '30m'
},
// 突发流量(模拟促销)
flash_sale: {
executor: 'ramping-vus',
stages: [
{ duration: '2m', target: 500 },
{ duration: '3m', target: 500 },
{ duration: '2m', target: 100 }
],
startTime: '15m' // 在正常负载15分钟后启动
}
}
3. 场景间数据共享
// 全局共享数据
const authTokens = new Map();
export function setup() {
// 预先生成认证令牌
for (let i = 1; i <= 100; i++) {
authTokens.set(`user_${i}`, generateToken());
}
return authTokens;
}
export function loginFlow(data) {
// 使用共享的认证令牌
const token = data.get(`user_${__VU}`);
}
4. 场景特定的环境变量
scenarios: {
staging_test: {
executor: 'constant-vus',
vus: 10,
duration: '10m',
env: { BASE_URL: 'https://staging.example.com' },
exec: 'mainFlow'
},
production_test: {
executor: 'constant-vus',
vus: 5,
duration: '5m',
env: { BASE_URL: 'https://api.example.com' },
exec: 'mainFlow'
}
}
高级场景配置
优雅停止和启动
scenarios: {
critical_checkout: {
executor: 'ramping-arrival-rate',
startRate: 5,
timeUnit: '1s',
stages: [
{ target: 10, duration: '30s' },
{ target: 10, duration: '5m' }
],
gracefulStop: '2m', // 优雅停止时间
preAllocatedVUs: 5,
maxVUs: 50
}
}
场景标签
scenarios: {
eu_users: {
executor: 'constant-vus',
vus: 20,
duration: '10m',
tags: { region: 'europe' },
exec: 'userFlow'
},
us_users: {
executor: 'constant-vus',
vus: 30,
duration: '10m',
tags: { region: 'usa' },
exec: 'userFlow'
}
}
总结
k6 中的场景是一个强大的功能,它允许您:
定义多种负载模式和测试策略
模拟真实世界的用户行为
并行测试系统的不同部分
收集细粒度的性能指标
优化测试资源的使用
通过合理使用场景,您可以创建更真实、更高效的性能测试,更准确地评估系统在各种条件下的表现,从而更好地发现和解决性能瓶颈。