跳转到内容

Grafana k6 性能测试入门:编写、运行和分析负载测试

k6 是 Grafana 旗下开源的性能测试工具,使用 JavaScript 编写测试脚本,轻量、CLI 友好、易于集成 CI/CD。它专注于开发者体验和自动化测试,相比 JMeter 更现代化。

终端窗口
# macOS
brew install k6
# Linux
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-get update && sudo apt-get install k6
# Docker
docker run --rm -i grafana/k6 run - <script.js

k6 脚本就是一个 JavaScript 文件,包含 export default function() 作为每个 VU(Virtual User)的执行体:

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("https://api.example.com/users");
check(res, {
"status is 200": (r) => r.status === 200,
"response time < 500ms": (r) => r.timings.duration < 500
});
sleep(1);
}

k6 自动收集以下指标,无需额外配置:

指标 说明
http_req_duration HTTP 请求总耗时(含 DNS、连接、TLS、响应)
http_req_failed 请求失败率
http_reqs 请求总数和速率
vus 活跃虚拟用户数
iterations 迭代次数
checks 自定义检查通过率

k6 支持多种负载模型(Executor),可根据测试目的组合使用:

export const options = {
scenarios: {
// 阶梯式增加负载
ramp_up: {
executor: "ramping-vus",
startVUs: 0,
stages: [
{ duration: "30s", target: 20 }, // 30s 内升至 20 VU
{ duration: "1m", target: 20 }, // 维持 1 分钟
{ duration: "30s", target: 0 } // 30s 内降至 0
]
},
// 恒定吞吐量
constant_rate: {
executor: "constant-arrival-rate",
rate: 50, // 每秒 50 个请求
timeUnit: "1s",
duration: "1m",
preAllocatedVUs: 20
}
}
};
执行器 用途
shared-iterations 固定总迭代次数,所有 VU 共享
per-vu-iterations 每个 VU 执行固定次数
constant-vus 固定 VU 数,持续指定时长
ramping-vus 阶段性增加/减少 VU 数
constant-arrival-rate 固定请求速率(吞吐量优先)
import { Trend, Counter, Gauge } from "k6/metrics";
const loginDuration = new Trend("login_duration");
const loginFailures = new Counter("login_failures");
export default function () {
const res = http.post("https://api.example.com/login", {
username: "user",
password: "pass"
});
loginDuration.add(res.timings.duration);
if (res.status !== 200) {
loginFailures.add(1);
}
}

通过 thresholds 在命令行输出中直接看到测试通过/失败:

export const options = {
thresholds: {
http_req_duration: ["p(95)<500"], // P95 延迟 < 500ms
http_req_failed: ["rate<0.01"], // 失败率 < 1%
login_duration: ["p(99)<1000"], // 自定义指标 P99 < 1s
checks: ["rate>0.95"] // Check 通过率 > 95%
}
};

阈值不满足时,k6 以非零状态码退出——CI 可直接根据退出码判断测试是否失败。

终端窗口
k6 run --summary-trend-stats="avg,min,med,max,p(95),p(99)" script.js
终端窗口
k6 run --out cloud script.js
# 或使用环境变量
K6_CLOUD_TOKEN=<token> k6 run --out cloud script.js
终端窗口
# InfluxDB
k6 run --out influxdb=http://localhost:8086/k6 script.js
# Prometheus Remote Write
k6 run --out experimental-prometheus-rw script.js
# GitHub Actions 示例
- name: Run k6 test
uses: grafana/[email protected]
with:
path: tests/k6/load-test.js
# 或直接在容器中运行
- name: k6 load test
run: |
k6 run tests/k6/load-test.js

结合阈值和 CI,可在每次 PR 中运行基准测试,拦截性能回归:

export const options = {
thresholds: {
// 与基准对比(需 k6 Cloud 或 xk6-benchmark)
"http_req_duration{endpoint:/api/search}": ["p(95)<baseline*1.1"]
}
};
const users = JSON.parse(open("./users.json"));
export default function () {
const user = users[__VU % users.length]; // 每个 VU 使用不同的用户
http.post("https://api.example.com/login", JSON.stringify(user));
}
export default function () {
const loginRes = http.post('https://api.example.com/login', { ... });
const token = loginRes.json('token');
const params = {
headers: { Authorization: `Bearer ${token}` },
};
http.get('https://api.example.com/protected', params);
}

k6 的优势在于脚本即代码(可直接存入 Git)、CLI 友好(CI 零成本集成)、内置丰富的指标和阈值机制。对于 API 性能测试和负载测试场景,是取代 JMeter 的优秀选择。当前限制是 k6 基于 Go+JS 架构,不支持真实浏览器渲染——如需前端性能测试需配合 Grafana Faro 或 Playwright。