- Published on
k6 负载测试全面指南:从脚本编写到结果可视化
- Authors
- Name
- Liant
k6 简述
k6脚本生命周期
地址:https://k6.io/docs/using-k6/test-life-cycle/
有4个不同的阶段
- 初始化
- 设置
- VU 代码
- 拆解

1、K6的功能
请求方式
k6请求方式地址:https://k6.io/docs/javascript-api/k6-http/
get
{run_k6}
http.get('url');
post
{run_k6_post}
http.post(url, payload, params);
payload:参数
params:请求头
const params = {
headers: {
'Content-Type': 'application/json',
'X-Client-Id': client_id,
'X-Timestamp':timestr,
'X-Random':randomint,
'X-Signature':sign
},
};
批处理
{run_k6_batch}
方式:
1、请求参数为对象
2、请求参数为对象,且具有命名属性
3、请求参数为数组
4、请求参数为URL 字符串的数组
一起请求时,请求url顺序不固定
指标
指标地址:https://k6.io/docs/using-k6/metrics/
内置指标
vus:当前活动虚拟用户数
vus_max:最大可能数量的虚拟用户
iterations:虚拟用户执行 JS 脚本的总次数
iteration_duration:完成一次完整请求所花费的时间
dropped_iterations:由于缺少 VU(对于到达率执行程序)或缺少时间(在基于迭代的执行程序中已过期的 maxDuration)而未启动的迭代次数
解释:设置了iterations,maxDuration就可能出现这种情况;例:总次数为10000,最大持续时间为:为5s
data_received:接收的数据
data_sent:发送的数据量
checks:成功率
特定于 HTTP 的内置指标
仅当测试发出 HTTP 请求时,才会生成这些指标
http_reqs:生成的 HTTP 请求总数
http_req_blocked:在发起请求之前等待的时间
http_req_connecting:建立到远程主机的TCP连接所花费的时间
http_req_tls_handshaking:与远程主机握手TLS会话所花费的时间
http_req_sending:向远程主机发送数据所花费的时间
http_req_waiting:等待远程主机响应所花费的时间
http_req_receiving:从远程主机接收响应数据所花费的时间
http_req_duration:远程服务器处理请求和响应需要多长时间,不包含初始的DNS查找/连接时间
http_req_duration = http_req_sending+http_req_waiting+http_req_receiving
http_req_failed:请求失败率,响应status code不为200-400之间
指标类型
Counter:求和
Gauge:展示添加的数据最小值,最大值
Rate:展示百分比
Trend:展示最小值、最大值、平均值,百分位数,90%的值,95%的值
自定义指标
{run_k6_batch}
1、引入依赖
2、声明自定义指标类型
3、将数据添加到自定义指标
检查
检查是测试运行时值的真/假条件
{run_k6_check}
1、系统以 200 状态响应
2、响应正文包含某些文本
3、响应正文具有指定的大小
检查失败正常情况下不会使测试失败,只会增加检查失败率,如果要使测试失败,需要添加阈值
{run_k6_check_thresholds}
方式一:根据所有检查结果判断
export const options = {
vus: 2,
duration: '2s',
thresholds: {
checks: ['rate>0.9'], //检查成功率大于0.9,否,终止测试
},
};
方式二:根据标签判断 {run_k6_check_thresholds_too}
export const options = {
vus: 2,
duration: '2s',
thresholds: {
'checks{mytag:mytag}': ['rate>0.9'], //检查成功率大于0.9,否,终止测试
},
};
阈值
阈值是测试指标的通过/失败条件
阈值类型是根据指标类型添加
1、Counter:计数器,用于数值累计求和后的判断
例如:响应时间<1s
2、Gauge:轨距,用于固定值判断
例如:接口响应大小<400字节
3、Rate:率,用于固定百分比判断
例如:错误率<99%
4、Trend:趋势,用于平均值,最大值,最小值,百分90等值的判断
5、添加check的阈值
6、添加标签子指标
格式:
{run_k6_thresholds}
export const options = {
vus: 3,
duration: '10s',
thresholds: {
checks: ['rate>0.9'], //检查成功率大于0.9
time: ['avg<200'], //平均时间的接口运行时间小于500ms
s_rate: ['rate>0.95'], //响应状态码为200的请求需大于95%
ContentSize: ['value<1000'],//接口响应体大小需小于1000字节
err: ['count<5'], // 错误量需小于5
'http_req_waiting{type: tag_value}': ['p(95)>200'],//标签为type: tag_value 的95%的等待时间大于200MS
},
};
options 选项
参考地址:https://k6.io/docs/using-k6/k6-options/reference/
优先级:
命令行>环境变量>脚本设置>配置文件>默认值
{run_k6_options}
discardResponseBodies: true --不返回请求的响应结果
{run_k6_api}
设置为true时,可在单个http请求后面,加 { responseType: 'text' }
const res = http.post(url, body,{ responseType: 'text' });
场景
执行固定的请求数量---shared-iterations
{run_k6_scene}
总请求数量 = iterations
scenarios: {
contacts: { //方案名,也可以是标签名
executor: 'shared-iterations',
vus: 10,
iterations: 200,
maxDuration: '30s',
},
},
每个虚拟用户固定请求次数---per-vu-iterations
{run_k6_scene_1}
总请求次数= uv * iterations
scenarios: {
contacts: {
executor: 'per-vu-iterations',
vus: 10,
iterations: 200,
maxDuration: '30s',
},
},
固定虚拟用户数,执行固定时间---constant-vus
{run_k6_scene_1}
html: {
executor: 'constant-vus',
vus: 10,
duration: '4m',
}
在固定时间段增加或减少虚拟用户数---ramping-vus
scenarios: {
contacts: {
executor: 'ramping-vus',
startVUs: 0,
stages: [ // 阶段,必传;0-20S内虚拟用户数增加到20,20s-30s虚拟用户数减少到0
{ duration: '20s', target: 10 },
{ duration: '10s', target: 0 },
],
gracefulRampDown: '0s',//到达最大持续时间,已经发起请求的数据,可停止时间
},
},
在某一秒发起固定的请求---constant-arrival-rate(类似集合点)
scenarios: { //每一秒运行30次脚本,持续时间为30s
contacts: {
executor: 'constant-arrival-rate',
duration: '30s',
rate: 30,
timeUnit: '1s',// 非必填
preAllocatedVUs: 2,
maxVUs: 50,//非必填
},
},
在某一秒发起固定的请求---ramping-arrival-rate(类似集合点)
scenarios: { // 在某一个时间段,以每秒30次的迭代增加到目标值
contacts: {
executor: 'ramping-arrival-rate',
startRate: 300,
rate: 30,//非必填
timeUnit: '1s',//非必填
preAllocatedVUs: 2,
maxVUs: 50,//非必填
stages: [
{ target: 300, duration: '1m' },
{ target: 600, duration: '2m' },
{ target: 600, duration: '4m' },
{ target: 60, duration: '2m' },
],
},
},
限制最大用户数 -----externally-controlled
scenarios: {
contacts: {
executor: 'externally-controlled',
vus: 10,
maxVUs: 50,
duration: '10m',
},
},
报告
官网报告
- 在官网注册账号
- 在个人信息,点击API token
- 复制个人API token
- 在本地命令行登录账号
k6 login cloud --token 5a774f670ac
- 运行脚本 添加
--out cloud
:k6 run --out cloud .\run_files\run_k6_api.js
控制台会展示报告地址:https://app.k6.io/runs/1454742
本地生成HTML报告
- 下载文件到本地:https://github.com/benc-uk/k6-reporter
- 脚本新增
import { htmlReport } from "https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js"; import { textSummary } from "https://jslib.k6.io/k6-summary/0.0.1/index.js"; export function handleSummary(data) { return { "result.html": htmlReport(data), stdout: textSummary(data, { indent: " ", enableColors: true }), }; }
Grafana
地址:https://k6.io/docs/results-visualization/influxdb-+-grafana/
k6 run .\run_files\run_k6_high_api.js --out influxdb=http://172.16.5.110:8086/k6
运行命令
k6 run XXX.js
运行结果

增加虚拟用户数(VU),脚本持续运行时间(s)
命令行的方式
-- vus X --duration X(s)
- 为中文段横杆
k6 run --vus 10 --duration 2s .\run_files\run_k6.js
代码添加方式
export const options = {
vus: 10,
duration: '30s',
};
k6 run .\run_files\run_k6_vus_duration.js

实现梯步增加虚拟用户数
场景是:0-30s用户数增加到20,30s-2m用户数减少到10,2m-2m20s用户数减少到0
30S用户数增加到20个,1m30s用户数减少到10,20s用户数减少到0
export const options = {
stages: [
{ duration: '30s', target: 20 },
{ duration: '1m30s', target: 10 },
{ duration: '20s', target: 0 },
],
};