K6是一款现代化的开源负载测试工具,专为开发和测试人员设计,可以使用JavaScript编写测试脚本。以下是完整的K6压测教程。
一、安装K6
二、编写第一个测试脚本
创建一个名为test.js
的文件:
import http from 'k6/http';
import { check, sleep } from 'k6';
// 初始化选项
export let options = {
vus: 10, // 虚拟用户数
duration: '30s', // 测试持续时间
};
export default function () {
// 发送HTTP GET请求
let res = http.get('https://test-api.k6.io/public/crocodiles/');
// 验证响应状态码是否为200
check(res, {
'is status 200': (r) => r.status === 200,
});
// 每个VU每次迭代后暂停1秒
sleep(1);
}
三、运行测试
在终端运行:
k6 run test.js
四、进阶测试脚本
1. 带参数的POST请求
import http from 'k6/http';
import { check, sleep } from 'k6';
export let options = {
stages: [
{ duration: '30s', target: 20 }, // 30秒内逐步增加到20个VU
{ duration: '1m', target: 20 }, // 保持20个VU1分钟
{ duration: '30s', target: 0 }, // 30秒内逐步减少到0
],
};
export default function () {
// POST请求数据
let data = JSON.stringify({
username: 'test_user',
password: 'test_password',
});
let params = {
headers: {
'Content-Type': 'application/json',
},
};
let res = http.post('https://test-api.k6.io/auth/token/login/', data, params);
check(res, {
'login successful': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
sleep(1);
}
2. 使用CSV数据驱动测试
创建users.csv
文件:
username,password
user1,pass1
user2,pass2
user3,pass3
测试脚本:
import http from 'k6/http';
import { check, sleep } from 'k6';
import { SharedArray } from 'k6/data';
// 读取CSV文件
const users = new SharedArray('users', function () {
return open('./users.csv').split('\n').slice(1).map((line) => {
const parts = line.split(',');
return { username: parts[0], password: parts[1] };
});
});
export let options = {
vus: 10,
duration: '1m',
};
export default function () {
// 获取当前VU的用户数据
const user = users[__VU % users.length];
let data = JSON.stringify({
username: user.username,
password: user.password,
});
let params = {
headers: {
'Content-Type': 'application/json',
},
};
let res = http.post('https://test-api.k6.io/auth/token/login/', data, params);
check(res, {
'login successful': (r) => r.status === 200,
});
sleep(1);
}
3. 测试RESTful API完整流程
import http from 'k6/http';
import { check, group, sleep } from 'k6';
export let options = {
stages: [
{ duration: '30s', target: 20 },
{ duration: '1m', target: 50 },
{ duration: '20s', target: 0 },
],
thresholds: {
http_req_duration: ['p(95)<500'], // 95%的请求响应时间应小于500ms
'logged in successfully': ['rate>0.9'], // 登录成功率应大于90%
},
};
export default function () {
// 1. 登录获取token
group('Authentication', function () {
let loginRes = http.post('https://test-api.k6.io/auth/token/login/', {
username: 'test_user',
password: 'test_password',
});
check(loginRes, {
'logged in successfully': (resp) => resp.json('access') !== '',
});
let authHeaders = {
headers: {
Authorization: `Bearer ${loginRes.json('access')}`,
},
};
// 2. 获取用户信息
let userRes = http.get('https://test-api.k6.io/auth/users/me/', authHeaders);
check(userRes, {
'retrieved user info': (r) => r.status === 200,
});
// 3. 创建资源
let createRes = http.post(
'https://test-api.k6.io/public/crocodiles/',
{
name: `Croc_${__VU}_${__ITER}`,
sex: 'M',
date_of_birth: '2020-01-01',
},
authHeaders
);
check(createRes, {
'created resource': (r) => r.status === 201,
});
let crocId = createRes.json('id');
// 4. 获取创建的资源
let getRes = http.get(`https://test-api.k6.io/public/crocodiles/${crocId}/`, authHeaders);
check(getRes, {
'retrieved created resource': (r) => r.status === 200,
});
// 5. 删除资源
let deleteRes = http.del(`https://test-api.k6.io/public/crocodiles/${crocId}/`, null, authHeaders);
check(deleteRes, {
'deleted resource': (r) => r.status === 204,
});
});
sleep(1);
}
五、结果分析与可视化
1. 输出结果到文件
k6 run --out json=result.json test.js
k6 run --out csv=result.csv test.js
2. 使用InfluxDB和Grafana可视化
- 安装InfluxDB和Grafana
- 运行测试时将结果发送到InfluxDB:
k6 run --out influxdb=http://localhost:8086/k6 test.js
- 在Grafana中配置InfluxDB数据源
- 导入K6仪表板模板
3. 使用k6 Cloud
如果你使用k6 Cloud,可以直接:
k6 login cloud --token YOUR_TOKEN
k6 cloud test.js
六、高级功能
1. 自定义指标
import http from 'k6/http';
import { check, sleep, group, trend } from 'k6';
// 创建自定义趋势指标
let responseTrend = new trend('response_time');
export let options = {
vus: 10,
duration: '1m',
};
export default function () {
group('API Test', function () {
let res = http.get('https://test-api.k6.io/public/crocodiles/');
// 记录响应时间到自定义指标
responseTrend.add(res.timings.duration);
check(res, {
'is status 200': (r) => r.status === 200,
'response time < 500ms': (r) => r.timings.duration < 500,
});
});
sleep(1);
}
2. 使用WebSocket
import ws from 'k6/ws';
import { check, sleep } from 'k6';
export let options = {
vus: 10,
duration: '30s',
};
export default function () {
let url = 'ws://echo.websocket.org';
let response = ws.connect(url, null, function (socket) {
socket.on('open', function open() {
socket.send('hello');
});
socket.on('message', function (message) {
console.log('Received: ', message);
socket.close();
});
socket.on('close', function () {
console.log('disconnected');
});
});
check(response, { 'status is 101': (r) => r && r.status === 101 });
sleep(1);
}
3. 分布式测试
使用k6 Operator在Kubernetes集群上运行分布式测试:
- 安装k6 Operator
- 创建测试资源文件
test.yaml
:apiVersion: k6.io/v1alpha1 kind: K6 metadata: name: k6-sample-test spec: parallelism: 4 script: configMap: name: k6-test-script file: test.js
- 应用配置:
kubectl apply -f test.yaml
七、常见问题解决
- 连接被拒绝:检查目标服务是否运行,防火墙设置
- SSL证书问题:添加
insecureSkipTLSVerify: true
到请求参数 - 内存不足:减少VU数量或增加
batch
/batchPerHost
参数 - 结果不一致:确保测试环境稳定,避免网络波动
通过以上教程,你可以使用K6和JavaScript编写全面的服务端压力测试脚本,并根据测试结果优化系统性能。