下载地址:
https://github.com/grafana/k6/releases
官方文档:
https://grafana.com/docs/k6/latest/
官方开源:
https://github.com/grafana/k6
关于 Grafana k6
- k6 是一款可靠性测试工具,能帮助开发者模拟真实用户行为,测试系统在相应情况下的表现,可在生产环境出现问题前识别出如响应缓慢、系统故障等潜在问题。
- 测试目标多样,包括检查性能、可靠性、可扩展性等,不同目标需不同配置,如模拟大量用户、长时间运行测试等。
- 测试脚本使用 JavaScript 或 TypeScript 编写,便于开发者使用,且易于集成到现有代码库和项目中。
开始前的准备
- 需具备 JavaScript 或 TypeScript 的基础知识,若不熟悉,可使用 k6 Studio 生成测试或探索其他测试创作方法。
- 需在机器上安装 k6。
- 需代码编辑器,如 Visual Studio Code、JetBrains 编辑器等,并可参考相关配置指南启用自动补全等功能。
k6 测试的基本结构
- 默认函数:是测试逻辑所在之处,定义了测试的操作和执行时的行为,需作为默认函数导出。
- 导入:可导入额外的 k6 模块或 JavaScript 库以扩展脚本功能,需注意 k6 有自己的 JavaScript 运行时,与部分 npm 模块的兼容性可能不同。
- 选项(可选):用于配置测试执行,如定义虚拟用户数量、测试持续时间、设置性能阈值等。
- 生命周期操作(可选):允许在测试逻辑执行前后运行代码,如从文件解析数据、从 Amazon S3 下载对象等,可通过预定义函数或特定代码范围实现。
编写第一个测试脚本步骤
// 导入k6的http模块,用于发送HTTP请求
import http from 'k6/http';
// 压测配置选项
export const options = {
// 指定总迭代次数:整个测试过程中会执行10次请求
// 迭代次数是所有虚拟用户(VUs)执行的总次数
iterations: 10,
// 注意:此处未指定vus(虚拟用户数),默认值为1
// 因此10次请求将由1个虚拟用户依次完成
};
// 定义默认的测试逻辑函数
// 每个虚拟用户会重复执行此函数,直到达到指定的迭代次数
export default function () {
// 发送GET请求到今日头条首页
// http.get()方法返回一个响应对象,包含状态码、响应时间等信息
http.get('https://www.toutiao.com');
}
/*
脚本说明:
1. 该脚本会对"https://www.toutiao.com"发起10次GET请求
2. 由于未指定vus,默认使用1个虚拟用户串行执行所有请求
3. 运行命令:k6 run 脚本文件名.js
4. 执行后会输出请求成功率、响应时间等性能指标
*/
核心 HTTP 性能指标(重点关注)
假设完整报告包含以下指标,含义如下:
指标名称 | 示例值 | 含义解读 |
http_req.duration | avg=82.72ms min=77.26ms | 请求响应时间(关键指标): |
http_req.failed | 0.00% 0 10 | 请求失败率: |
http_req.received | 1.2MB 120KB/s | 总接收数据量及平均每秒接收数据量(反映接口返回数据大小) |
http_req.sent | 8.5KB 0.85KB/s | 总发送数据量及平均每秒发送数据量(反映请求体大小) |
http_reqs | 10 1.00/s | 总请求数及吞吐量(RPS,每秒完成的请求数) |
结果分析建议
- 响应时间:若p(95)接近或超过预期阈值(如 500ms),说明接口在高百分位请求中响应较慢,可能需要优化。你的示例中avg=82.72ms,属于较快水平,性能表现良好。
- 失败率:0% 失败率说明接口稳定性较好,若存在失败,需查看具体错误(如状态码非 200、超时等)。
- 场景优化:当前脚本无并发(VUs=1),仅能测试单用户场景下的接口性能。若需测试并发能力,可在options中添加vus: 10(10 个并发用户)和duration: '30s'(持续 30 秒),模拟多用户同时访问。
结合具体案例举例,帮助理解实际配置思路:
一、并发控制策略
1. 简单场景:vus + duration快速创建固定并发
适用场景:快速验证接口基本性能(如开发自测、单接口冒烟测试),无
为助力理解实际配置思路,现结合具体案例展开阐述:
一、并发控制策略
1. 简单场景:vus + duration 快速创建固定并发
适用情境:此策略适用于快速验证接口基本性能的场景,诸如开发自测、单接口冒烟测试等,无需模拟复杂的流量变化。
示例:以测试登录接口在 100 个用户同时访问时持续 30 秒的表现为例,代码如下:
export const options = {
vus: 100, // 固定 100 个并发用户
duration: '30s' // 持续压测 30 秒
};
特点:该配置方式简便易行,虚拟用户数量自始至终保持恒定,适宜开展初步的性能摸底工作。
2. 真实流量:stages 模拟负载变化(生产环境推荐)
适用情境:此策略可用于模拟真实业务流量曲线,例如电商促销活动从预热阶段到高峰时段再到回落过程的流量变化,能更贴合线上实际状况。
示例:模拟电商秒杀活动的流量变化,代码如下:
export const options = {
stages: [
{ duration: '1m', target: 200 }, // 预热 1 分钟,逐步升至 200 并发(用户陆续进入)
{ duration: '30s', target: 500 }, // 30 秒内升至 500 并发(秒杀开始,流量激增)
{ duration: '2m', target: 500 }, // 保持 500 并发 2 分钟(秒杀高峰期)
{ duration: '30s', target: 100 }, // 30 秒内降至 100 并发(秒杀结束,流量回落)
]
};
特点:借助阶梯式负载,能够观察系统在不同压力状态下的性能演变情况,例如是否在流量增长时出现响应时间陡然增加的现象。
3. 复杂场景:scenarios 配置多类型用户行为
适用情境:当系统存在多种用户行为时,如电商平台的 “浏览商品” 和 “下单支付” 等,需要模拟混合场景,此策略便派上用场。
示例:同时模拟两种用户行为,比例设定为 8:2,代码如下:
export const options = {
scenarios: {
// 场景1:浏览商品(占比80%)
browse: {
executor: 'constant-vus', // 固定并发执行器
vus: 80, // 80个用户
duration: '5m', // 持续5分钟
exec: 'browseProducts' // 绑定浏览逻辑函数
},
// 场景2:下单支付(占比20%)
pay: {
executor: 'ramping-vus', // 渐变并发执行器
startVUs: 10, // 初始10个用户
stages: [{ duration: '5m', target: 20 }], // 5分钟内升到20个用户
exec: 'submitOrder' // 绑定下单逻辑函数
}
}
};
// 浏览商品逻辑
export function browseProducts() { /* ... */ }
// 下单支付逻辑
export function submitOrder() { /* ... */ }
特点:多场景并行,可模拟真实业务中不同操作的混合比例,更全面评估系统性能。
二、性能阈值设计原则
1. 核心指标:http_req_failed和http_req_duration必选
作用:衡量接口可用性和响应速度,是性能测试的基础指标。
举例:
thresholds: {
http_req_failed: ['rate<0.01'], // 失败率 < 1%(即成功率 > 99%)
http_req_duration: ['p(95)<800'] // 95%的请求响应时间 < 800ms
}
解读:
失败率超过 1% → 系统稳定性不足(如频繁超时、错误)。
95% 响应时间 > 800ms → 大部分用户会感受到明显延迟。
2. 业务导向:根据 SLA 设定阈值
原则:阈值需与业务承诺的服务等级(SLA)对齐,核心接口严于非核心接口。
举例:
- 核心接口(如支付):SLA 要求 99.9% 请求 < 500ms → http_req_duration: ['p(99.9)<500']。
- 非核心接口(如商品评论列表):SLA 要求 95% 请求 < 2000ms → http_req_duration: ['p(95)<2000']。
3. 错误细分:区分5xx和4xx错误
原则:5xx(服务器错误)通常是系统问题(需严格限制),4xx(客户端错误)可能是用户输入问题(可适当放宽)。
举例:
thresholds: {
'http_req_status{status:500}': ['rate<0.001'], // 500错误率 < 0.1%(不允许频繁服务崩溃)
'http_req_status{status:400}': ['rate<0.05'] // 400错误率 < 5%(允许少量用户输入错误)
}
三、资源优化技巧
1.preAllocatedVUs设为峰值的 50%-80%
作用:预分配部分虚拟用户,减少测试中动态创建 / 销毁 VUs 的性能开销(避免压测工具自身成为瓶颈)。
举例:
若峰值并发为 1000VUs → 预分配 500-800VUs:
export const options = {
vus: 1000,
preAllocatedVUs: 600 // 预分配60%的峰值VUs,平衡内存和性能
};
2. 高并发场景开启discardResponseBodies: true
作用:高并发(>1000VUs)时,响应体可能占用大量内存,导致 k6 性能下降。开启后不保存响应体,节省资源。
举例:
export const options = {
vus: 2000,
discardResponseBodies: true // 高并发下关闭响应体保存
};
注意:若需断言响应内容(如check(res, { 'code==0': r => r.json().code===0 })),则不能开启。
3. 限制rps避免压测工具瓶颈
作用:当 k6 所在机器性能不足时,限制每秒请求数(RPS),确保测试结果反映的是被测系统性能,而非工具本身。
举例:
已知压测机最大能稳定发送 1000RPS → 限制为 800RPS:
export const options = {
rps: 800, // 每秒最多发送800个请求
vus: 200
};
四、结果分析建议
1. 本地调试:logLevel: 'debug'+ JSON 输出
适用场景:脚本开发阶段,需排查请求失败原因(如参数错误、响应异常)。
举例:
export const options = {
logLevel: 'debug', // 输出详细日志(包括请求头、响应体)
ext: {
json: { output: 'debug-results.json' } // 保存结果到JSON文件
}
};
分析方式:查看 JSON 中的http_req细节,或通过console.log打印关键信息。
2. 生产压测:集成 InfluxDB+Grafana 长期分析
适用场景:生产环境压测,需长期跟踪性能趋势(如版本迭代后性能是否退化)。
配置举例:
export const options = {
ext: {
influxdb: {
url: 'http://influxdb-server:8086', // InfluxDB地址
db: 'k6_prod', // 数据库名
tags: { version: 'v2.3.0' } // 标记当前测试的版本
}
}
};
分析方式:在 Grafana 中创建仪表盘,展示响应时间、失败率等指标的趋势图,对比不同版本的性能差异。
3. 对比测试:通过tags标记不同维度
作用:用标签区分测试环境、版本、场景,便于筛选和对比结果。
举例:
export const options = {
tags: {
environment: 'staging', // 测试环境(开发/测试/生产)
version: 'v2.3.0', // 被测系统版本
scenario: 'peak' // 测试场景(日常/高峰)
}
};
分析方式:在测试报告中按tags筛选,例如对比v2.2.0和v2.3.0版本的性能差异,或生产与测试环境的表现。
通过以上配置和案例,可以根据实际测试目标(如功能验证、性能瓶颈分析、SLA 达标验证)灵活调整参数,使压测结果更具参考价值。
最终的脚本
import http from 'k6/http';
export const options = {
// 核心并发与时长配置
vus: 1000,
//duration: '60s',
// 分阶段施压(v1.1.0完全支持)
stages: [
{ duration: '10s', target: 300 },
{ duration: '15s', target: 600 },
{ duration: '20s', target: 1000 },
{ duration: '15s', target: 500 },
],
// 性能阈值(修正v1.1.0支持的语法)
thresholds: {
http_req_failed: ['rate<0.01'], // 失败率<1%(支持)
http_req_duration: ['p(95)<800'], // 95%响应时间<800ms(支持)
// v1.1.0不支持http_req_status带标签筛选,改用http_req_failed间接监控
},
// 资源优化配置(v1.1.0支持)
//preAllocatedVUs: 500,
//maxVUs: 1200,
// 超时控制(v1.1.0中gracefulStop需用全称gracefulStopSeconds)
//httpReqTimeout: '10s',
//gracefulStopSeconds: 20, // 注意:v1.1.0中参数名为gracefulStopSeconds(而非gracefulStop)
// 日志与调试(v1.1.0支持)
//logLevel: 'warn',
discardResponseBodies: false,
// 标签(v1.1.0支持)
tags: {
testType: 'load',
target: 'api',
priority: 'high'
}
};
export default function () {
http.get('https://www.toutiao.com');
}
阈值验证(THRESHOLDS)
这部分是压测前设定的 “及格线”,用于自动判断压测是否通过,是最核心的结果判断依据:
阈值项 | 规则 | 实际结果 | 结论 | 解读 |
http_req_duration | p(95) < 800 | p(95)=829.82ms | 不通过 | 95% 的请求响应时间 829.82ms,超过了设定的 800ms 阈值,说明高比例请求响应较慢 |
http_req_failed | rate < 0.01 | rate=0.06% | 通过 | 请求失败率 0.06%(80/128034),低于 1% 阈值,接口整体可用性达标 |
关键结论:
核心性能指标(TOTAL RESULTS → HTTP)
这部分聚焦 HTTP 请求的性能表现,是分析系统吞吐量、响应速度的关键:
1.http_req_duration(请求响应时间)
指标细分 | 平均值 (avg) | 最小值 (min) | 中位数 (med) | 最大值 (max) | 90 分位 (p90) | 95 分位 (p95) | 解读 |
所有请求 | 303.06ms | 0ms | 175.83ms | 38.74s | 657.55ms | 829.82ms | 平均响应 303ms,但最大响应达 38.74s(可能存在长尾请求或偶发超时) |
{ expected_response:true } | 303.25ms | 63.53ms | 175.89ms | 38.74s | 657.77ms | 829.93ms | 过滤后(仅正常响应)的请求,趋势与整体一致,排除了异常短 / 超时的干扰 |
问题点:
- max=38.74s 说明存在极少数请求响应极慢(可能是网络波动、服务器阻塞或超时重传导致)。
- p95=829.82ms 超过阈值,95% 的用户会感受到明显延迟(接近 1 秒)。