3. k6 脚本核心语法(一):VU 与迭代概念、default 函数、http.get 请求、检查点(check)与阈值(threshold)入门
本章是 k6 脚本开发的起点。你将理解 k6 最核心的执行模型——虚拟用户(VU)与迭代(Iteration),掌握脚本入口函数 default 的写法,发起第一个 HTTP GET 请求,并通过检查点(check)和阈值(threshold)验证请求结果。这些概念将贯穿整个压测脚本开发过程。
3.1 VU 与迭代:k6 的执行模型
k6 采用“虚拟用户(VU)循环执行迭代”的并发模型。理解这个模型是编写正确脚本的前提。
核心公式: 总请求数 ≈ VU 数 × 每个 VU 的迭代次数 × 每次迭代中的请求数
| 概念 | 说明 | 类比 |
|---|---|---|
| VU(虚拟用户) | 模拟一个真实用户,独立运行 JavaScript 代码的并发实体 | 一个独立的“机器人” |
| 迭代(Iteration) | 每个 VU 从 default 函数开始到结束的一次完整执行 |
机器人完成一次“任务循环” |
| VU 数 | 同时运行的虚拟用户数量,通过 --vus 或 options 设置 |
机器人的数量 |
| 迭代次数 | 每个 VU 执行的迭代总数,通过 --iterations 或 options 设置 |
每个机器人跑多少轮 |
3.2 default 函数:脚本的入口
k6 脚本的核心是一个名为 default 的导出函数。每个 VU 的每次迭代都会执行这个函数一次。脚本中只能有一个 default 函数。
import http from 'k6/http';
import { check, sleep } from 'k6';
// 每个 VU 的每次迭代都会执行 default 函数
export default function () {
let res = http.get('https://test.k6.io');
check(res, {
'状态码为 200': (r) => r.status === 200,
});
sleep(1);
}
提示:
default 函数之外的代码(如全局变量、导入语句、配置对象)只在脚本初始化阶段执行一次,不会被重复执行。这有助于节省资源,但要注意全局状态的管理。
3.3 发起 HTTP GET 请求
http.get(url, [params]) 是 k6 中最常用的请求方法。它返回一个 Response 对象,包含状态码、响应体、响应头等信息。
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
url |
string | 请求的目标 URL | 'https://api.example.com/users' |
params(可选) |
object | 包含 headers、tags、timeout 等配置 | { headers: { 'Authorization': 'Bearer xxx' } } |
import http from 'k6/http';
export default function () {
// 基本 GET 请求
let res = http.get('https://test.k6.io');
// 带请求头的 GET 请求
let resWithHeaders = http.get('https://api.example.com/data', {
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
tags: { name: '获取数据' }, // 自定义标签,用于结果分类
});
console.log(`状态码: ${res.status}`);
console.log(`响应体长度: ${res.body.length}`);
}
3.4 检查点(check):验证响应是否符合预期
check 函数用于对响应结果进行断言验证。它不会中断脚本执行,但会记录检查通过/失败的数量,并影响最终的阈值判定。
import http from 'k6/http';
import { check } from 'k6';
export default function () {
let res = http.get('https://test.k6.io');
// 单个检查
check(res, {
'状态码为 200': (r) => r.status === 200,
});
// 多个检查
check(res, {
'状态码为 200': (r) => r.status === 200,
'响应时间 < 2000ms': (r) => r.timings.duration < 2000,
'响应体包含 k6': (r) => r.body.includes('k6'),
});
}
注意: check 失败不会抛出异常或停止 VU 执行。如果你需要根据检查结果做分支逻辑,请使用普通的 if 语句。check 只用于“记录和统计”。
3.5 阈值(threshold):定义通过/失败标准
阈值是 k6 中定义性能验收标准的方式。它在脚本的 options 中声明,基于内置指标或自定义检查结果来判定压测是否通过。
import http from 'k6/http';
import { check } from 'k6';
import { Rate } from 'k6/metrics';
// 自定义指标:记录检查失败率
let failureRate = new Rate('failed_checks');
export let options = {
vus: 10,
iterations: 100,
thresholds: {
// 内置指标:95% 的请求响应时间 < 1500ms
http_req_duration: ['p(95)<1500'],
// 内置指标:请求失败率 < 1%
http_req_failed: ['rate<0.01'],
// 自定义指标:检查失败率 < 5%
'failed_checks': ['rate<0.05'],
},
};
export default function () {
let res = http.get('https://test.k6.io');
let checkResult = check(res, {
'状态码为 200': (r) => r.status === 200,
});
// 记录检查失败
failureRate.add(!checkResult);
}
| 阈值表达式 | 含义 | 适用场景 |
|---|---|---|
p(95)<2000 |
95% 的请求响应时间低于 2000ms | 响应时间达标验证 |
rate<0.01 |
失败率低于 1% | 错误率控制 |
avg<1000 |
平均响应时间低于 1000ms | 平均性能基线 |
count>=1000 |
总请求数至少达到 1000 | 压测量级验证 |
3.6 综合示例:第一个完整的压测脚本
将以上知识点整合,编写一个完整的压测脚本:
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';
// 自定义指标:记录检查失败率
let failureRate = new Rate('check_failure_rate');
export let options = {
vus: 5, // 5 个虚拟用户
iterations: 50, // 总共执行 50 次迭代
thresholds: {
// 95% 的请求响应时间 < 2000ms
http_req_duration: ['p(95)<2000'],
// 请求失败率 < 1%
http_req_failed: ['rate<0.01'],
// 自定义检查失败率 < 10%
'check_failure_rate': ['rate<0.1'],
},
};
export default function () {
// 1. 发起 GET 请求
let res = http.get('https://test.k6.io');
// 2. 执行检查点
let checkPassed = check(res, {
'状态码为 200': (r) => r.status === 200,
'响应时间 < 3000ms': (r) => r.timings.duration < 3000,
'页面包含 k6': (r) => r.body.includes('k6'),
});
// 3. 记录检查失败率
failureRate.add(!checkPassed);
// 4. 模拟用户思考时间
sleep(1);
}
最佳实践: 在开发阶段,可以先使用
k6 run script.js 在本地运行少量迭代(如 --iterations 10)来验证脚本逻辑。确认检查点和阈值配置正确后,再增加 VU 数和迭代次数进行正式压测。
3.7 本章小结
- VU 与迭代 是 k6 并发模型的基础,每个 VU 独立循环执行
default函数。 - default 函数 是脚本入口,每次迭代都会执行一次。
- http.get() 发起 HTTP GET 请求,返回 Response 对象。
- check() 用于验证响应结果,记录通过/失败次数。
- threshold 定义性能验收标准,基于聚合指标判定压测是否通过。