K6 性能负载测试工具教程
K6 是由 Grafana Labs 维护的现代化负载测试工具,使用 Go 语言构建,通过 JavaScript ES6 脚本定义测试场景。它拥有极低的资源消耗、丰富的协议支持和优秀的 CI/CD 集成能力。本文将介绍如何在搬瓦工 VPS 上部署 K6 并编写专业的性能测试方案。
一、安装 K6
# Ubuntu/Debian
sudo gpg -k
sudo gpg --no-default-keyring --keyring /usr/share/keyrings/k6-archive-keyring.gpg \
--keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D69
echo "deb [signed-by=/usr/share/keyrings/k6-archive-keyring.gpg] https://dl.k6.io/deb stable main" | \
sudo tee /etc/apt/sources.list.d/k6.list
sudo apt update
sudo apt install k6 -y
# CentOS/RHEL
sudo yum install https://dl.k6.io/rpm/repo.rpm -y
sudo yum install k6 -y
# 或使用二进制安装
wget https://github.com/grafana/k6/releases/latest/download/k6-linux-amd64.tar.gz
tar xzf k6-linux-amd64.tar.gz
mv k6-linux-amd64/k6 /usr/local/bin/
# 验证
k6 version
二、第一个测试脚本
cat > test.js <<'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
// 测试配置
export const options = {
vus: 10, // 10 个虚拟用户
duration: '30s', // 持续 30 秒
};
export default function () {
const res = http.get('http://localhost/');
// 检查响应
check(res, {
'status is 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1); // 每次请求间隔 1 秒
}
EOF
# 运行测试
k6 run test.js
三、负载模型配置
3.1 阶梯式负载
cat > stages-test.js <<'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
export const options = {
stages: [
{ duration: '2m', target: 50 }, // 2 分钟内增加到 50 用户
{ duration: '5m', target: 50 }, // 保持 50 用户 5 分钟
{ duration: '2m', target: 100 }, // 2 分钟内增加到 100 用户
{ duration: '5m', target: 100 }, // 保持 100 用户 5 分钟
{ duration: '2m', target: 0 }, // 2 分钟内降到 0
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95% 请求在 500ms 内完成
http_req_failed: ['rate<0.01'], // 失败率低于 1%
},
};
export default function () {
const res = http.get('http://localhost/');
check(res, {
'status is 200': (r) => r.status === 200,
});
sleep(1);
}
EOF
3.2 恒定请求速率
cat > constant-rate.js <<'EOF'
import http from 'k6/http';
import { check } from 'k6';
export const options = {
scenarios: {
constant_request_rate: {
executor: 'constant-arrival-rate',
rate: 100, // 每秒 100 个请求
timeUnit: '1s',
duration: '5m',
preAllocatedVUs: 50,
maxVUs: 200,
},
},
};
export default function () {
const res = http.get('http://localhost/');
check(res, {
'status is 200': (r) => r.status === 200,
});
}
EOF
四、高级测试场景
4.1 API 测试(POST/PUT/DELETE)
cat > api-test.js <<'EOF'
import http from 'k6/http';
import { check, group, sleep } from 'k6';
const BASE_URL = 'http://localhost:8080/api';
export const options = {
vus: 20,
duration: '3m',
};
export default function () {
group('User API', function () {
// 创建用户
const createRes = http.post(`${BASE_URL}/users`, JSON.stringify({
name: `user_${__VU}_${__ITER}`,
email: `user${__VU}@example.com`,
}), {
headers: { 'Content-Type': 'application/json' },
});
check(createRes, {
'user created': (r) => r.status === 201,
});
const userId = createRes.json('id');
// 获取用户
if (userId) {
const getRes = http.get(`${BASE_URL}/users/${userId}`);
check(getRes, {
'user found': (r) => r.status === 200,
});
// 删除用户
const delRes = http.del(`${BASE_URL}/users/${userId}`);
check(delRes, {
'user deleted': (r) => r.status === 204,
});
}
});
sleep(1);
}
EOF
4.2 带认证的测试
cat > auth-test.js <<'EOF'
import http from 'k6/http';
import { check } from 'k6';
export function setup() {
// setup 阶段只执行一次,获取 token
const loginRes = http.post('http://localhost:8080/api/login', JSON.stringify({
username: 'admin',
password: 'password',
}), {
headers: { 'Content-Type': 'application/json' },
});
return { token: loginRes.json('token') };
}
export default function (data) {
const params = {
headers: {
'Authorization': `Bearer ${data.token}`,
'Content-Type': 'application/json',
},
};
const res = http.get('http://localhost:8080/api/protected', params);
check(res, {
'authenticated request succeeded': (r) => r.status === 200,
});
}
EOF
五、阈值与自动判定
cat > threshold-test.js <<'EOF'
import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate, Trend } from 'k6/metrics';
// 自定义指标
const errorRate = new Rate('errors');
const apiDuration = new Trend('api_duration');
export const options = {
vus: 50,
duration: '5m',
thresholds: {
http_req_duration: ['p(95)<300', 'p(99)<500'],
http_req_failed: ['rate<0.01'],
errors: ['rate<0.05'],
api_duration: ['p(95)<200'],
},
};
export default function () {
const res = http.get('http://localhost/api/data');
const result = check(res, {
'status 200': (r) => r.status === 200,
'body not empty': (r) => r.body.length > 0,
});
errorRate.add(!result);
apiDuration.add(res.timings.duration);
sleep(0.5);
}
EOF
# 运行(阈值不满足时 k6 返回非零退出码)
k6 run threshold-test.js
echo "Exit code: $?"
六、输出与报告
# 输出 JSON 格式结果
k6 run --out json=results.json test.js
# 输出 CSV 格式
k6 run --out csv=results.csv test.js
# 输出到 InfluxDB(配合 Grafana 可视化)
k6 run --out influxdb=http://localhost:8086/k6 test.js
# 生成摘要报告到文件
k6 run --summary-export=summary.json test.js
七、与 CI/CD 集成
# GitHub Actions 示例
cat > .github/workflows/load-test.yml <<'EOF'
name: Load Test
on: [push]
jobs:
k6-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: grafana/k6-action@v0.3.1
with:
filename: test.js
flags: --vus 50 --duration 30s
EOF
总结
K6 将 JavaScript 的灵活性与 Go 的高性能完美结合,是现代化性能测试的首选工具。它的阈值功能特别适合集成到 CI/CD 流水线中,自动化性能回归检测。简单的基准测试也可以使用 wrk,模拟复杂用户行为可以使用 Locust。选购搬瓦工 VPS 请查看 全部方案,购买时使用优惠码 NODESEEK2026 可享受 6.77% 的折扣,通过 bwh81.net 访问官网。