在 k6 中,Scenario(场景) 是组织和管理复杂负载测试的核心概念,它允许用户在同一测试脚本中定义多种负载模式、执行策略和业务逻辑组合,从而更精准地模拟真实世界的用户行为。以下从核心概念、应用场景、配置方法和实际案例展开详解:
一、Scenarios 的核心概念
-
设计目标
- 灵活负载控制:替代传统的单一
vus
和duration
配置,支持多套独立的负载策略共存。 - 业务逻辑隔离:不同场景可关联独立的 JS 函数,模拟不同用户行为(如登录、下单、查询)。
- 并行/串行执行:场景间可并行加压或按顺序触发,适应复杂业务流程。
- 灵活负载控制:替代传统的单一
-
关键配置参数
参数 作用 示例值 executor
定义虚拟用户(VU)的执行逻辑(如固定并发、阶梯加压等) constant-vus
、ramping-vus
vus
当前场景的最大并发用户数 vus: 100
iterations
总迭代次数(与 duration
二选一)iterations: 1000
startTime
场景启动延迟(如 "10s"
表示测试开始10秒后启动该场景)startTime: "30s"
env
场景专属环境变量 env: { API_KEY: "test" }
-
核心 Executor 类型
-
constant-vus
:固定 VU 数量持续运行(例:{ executor: 'constant-vus', vus: 50, duration: '5m' }
)。 -
ramping-vus
:阶梯式调整 VU 数(例:stages: [{ duration: '2m', target: 200 }]
)。 -
shared-iterations
:所有 VU 共享总迭代次数(适合任务均匀分配)。 -
per-vu-iterations
:每个 VU 独立完成固定迭代次数(适合用户独立行为)。
-
二、Scenarios 的具体应用场景
混合业务流量模拟
需求:同时模拟“用户登录”和“商品浏览”两种行为,且登录请求量仅为浏览的 20%。
脚本示例:
export const options = {
scenarios: {
login: {
executor: 'constant-vus',
vus: 20, // 20% 流量
duration: '5m',
exec: 'loginUser' // 关联自定义登录函数
},
browse: {
executor: 'ramping-vus',
stages: [{ duration: '5m', target: 80 }], // 80% 流量
exec: 'browseProducts' // 关联商品浏览函数
}
}
};
export function loginUser() { /* 登录逻辑 */ }
export function browseProducts() { /* 浏览逻辑 */ }
峰值流量测试(尖峰测试)
需求:模拟秒杀场景,瞬时涌入 5000 用户,持续 30 秒后骤降。
配置:
scenarios: {
spike: {
executor: 'ramping-vus',
stages: [
{ duration: '5s', target: 5000 }, // 5秒内加压至5000 VU
{ duration: '30s', target: 5000 }, // 维持高压
{ duration: '5s', target: 0 } // 5秒内降为0
]
}
}
顺序执行依赖场景
需求:先初始化测试数据(setup
),再执行压测,最后清理数据(teardown
)。
实现:
scenarios: {
setup: {
executor: 'shared-iterations',
iterations: 1,
exec: 'setupData', // 初始化数据
startTime: '0s' // 立即启动
},
mainTest: {
executor: 'constant-vus',
vus: 100,
duration: '10m',
startTime: '1m' // 延迟1分钟等待setup完成
},
cleanup: {
executor: 'shared-iterations',
iterations: 1,
exec: 'teardown',
startTime: '11m' // 压测结束后启动
}
}
三、进阶技巧与最佳实践
-
标签(Tags)与阈值(Thresholds)联动
为不同场景的请求打标签,并设置独立阈值:
export default function () {
group('payment', () => {
const res = http.post('/pay', { tags: { scenario: 'checkout' } });
check(res, { 'status 200': (r) => r.status === 200 });
});
}
export const options = {
thresholds: {
'http_req_duration{scenario:checkout}': ['p(95) < 1000'], // 仅监控支付场景
}
};
-
资源隔离与错误处理
- 使用
scenario
专属环境变量避免全局污染:env: { DB_TABLE: "orders" }
。 - 通过
abortOnFail
参数控制单场景失败是否终止整个测试。
- 使用
-
动态数据驱动
结合SharedArray
为不同场景分配独立测试数据:const loginData = new SharedArray('login', () => JSON.parse(open('./login.json'))); const browseData = new SharedArray('browse', () => JSON.parse(open('./products.json')));
四、典型应用案例:电商全链路压测
目标:模拟用户从登录→浏览→下单的全流程。
脚本设计:
import http from 'k6/http';
import { group, check } from 'k6';
export const options = {
scenarios: {
login: {
executor: 'per-vu-iterations',
vus: 50,
iterations: 10,
exec: 'login'
},
checkout: {
executor: 'constant-vus',
vus: 30,
duration: '10m',
exec: 'checkout',
startTime: '1m' // 登录1分钟后启动下单
}
}
};
export function login() {
group('登录场景', () => {
http.post('/login', { username: `user${__VU}`, password: 'pass' });
});
}
export function checkout() {
group('下单场景', () => {
http.get('/cart');
http.post('/order');
});
}
关键优势:
- 行为隔离:登录用户与下单用户逻辑分离,避免互相干扰。
- 精准控制:登录阶段 50 VU 各执行 10 次;下单阶段固定 30 VU 持续 10 分钟。
五、常见问题与避坑指南
-
VU 资源竞争
问题:多个场景共享全局变量导致数据覆盖。
解决:使用scenario.env
或__VU
隔离数据。 -
启动时间冲突
问题:并行场景同时启动造成资源争抢。
解决:通过startTime
错峰启动(如间隔 30 秒)。 -
指标聚合混乱
问题:所有场景的 HTTP 指标混合统计。
解决:为请求添加tags: { scenario: "xxx" }
,并在阈值中按标签过滤。
总结:k6 的 Scenario 通过 多模式负载编排、业务逻辑解耦 和 精细化监控,解决了传统工具单一负载模型的局限性。尤其适用于:
- 混合业务流量的微服务压测
- 需顺序/并行控制的复杂流程
- 基于标签的精准性能分析
结合阈值与标签功能,可进一步实现 场景级性能 SLO 验证,是云原生全链路压测的首选方案。