使用 K6 进行性能测试:从安装到结果分析
K6 是一款现代化的开源性能测试工具,专为开发者和测试工程师设计。它使用 JavaScript 编写测试脚本,支持高并发负载测试,并提供丰富的性能指标和可视化报告。本文将介绍如何使用 Chocolatey 安装 K6,如何编写测试脚本,以及如何解读测试结果。
1. 使用 Chocolatey 安装 K6
Chocolatey 是 Windows 上的包管理工具,可以快速安装 K6。
安装步骤:
-
安装 Chocolatey(如果尚未安装):
以管理员身份打开 PowerShell,运行以下命令:Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
-
安装 K6:
在 PowerShell 中运行以下命令:choco install k6
-
验证安装:
安装完成后,运行以下命令检查 K6 是否安装成功:k6 version
如果显示 K6 的版本号,说明安装成功。
2. K6 的基本使用
K6 的核心是使用 JavaScript 编写测试脚本。以下是一个简单的 K6 测试脚本示例:
示例脚本:测试一个 API 的性能
import http from 'k6/http';
import { check, sleep } from 'k6';
// 测试配置
export let options = {
vus: 10, // 虚拟用户数
duration: '30s', // 测试持续时间
};
// 测试脚本
export default function () {
let response = http.get('https://test-api.com/endpoint'); // 测试的目标 API
check(response, {
'Status is 200': (r) => r.status === 200, // 检查响应状态码是否为 200
'Response time < 500ms': (r) => r.timings.duration < 500, // 检查响应时间是否小于 500ms
});
sleep(1); // 每个虚拟用户请求之间的间隔时间
}
脚本说明:
-
import
语句:
导入 K6 的模块,例如http
用于发送 HTTP 请求,check
用于断言,sleep
用于控制请求间隔。 -
options
对象:
定义测试的配置参数:vus
:虚拟用户数(并发用户数)。duration
:测试持续时间。
-
export default function
:
定义测试逻辑,每个虚拟用户会重复执行此函数。 -
http.get
:
发送 HTTP GET 请求到目标 API。 -
check
:
对响应结果进行断言,例如检查状态码和响应时间。 -
sleep
:
控制每个虚拟用户请求之间的间隔时间,单位为秒。
3. 运行 K6 测试
将上述脚本保存为 script.js
,然后在命令行中运行以下命令启动测试:
k6 run script.js
K6 会启动测试并输出实时结果。
4. 测试结果解读
K6 的测试结果会显示在终端中,包含以下关键指标:
示例输出:
running (30.0s), 00/10 VUs, 300 complete and 0 interrupted iterations
default ✓ [======================================] 10 VUs 30s
✓ Status is 200
✓ Response time < 500ms
checks.........................: 100.00% ✓ 600 ✗ 0
data_received..................: 1.2 MB 39 kB/s
data_sent......................: 45 kB 1.5 kB/s
http_req_blocked...............: avg=1.5ms min=0s med=1ms max=20ms p(90)=3ms p(95)=5ms
http_req_connecting............: avg=1ms min=0s med=1ms max=15ms p(90)=2ms p(95)=3ms
http_req_duration..............: avg=150ms min=100ms med=140ms max=300ms p(90)=200ms p(95)=250ms
http_req_receiving.............: avg=2ms min=1ms med=2ms max=10ms p(90)=3ms p(95)=4ms
http_req_sending...............: avg=1ms min=0s med=1ms max=5ms p(90)=2ms p(95)=3ms
http_req_waiting...............: avg=147ms min=90ms med=137ms max=290ms p(90)=195ms p(95)=245ms
http_reqs......................: 300 10.0/s
iteration_duration.............: avg=1.15s min=1.01s med=1.1s max=1.3s p(90)=1.2s p(95)=1.25s
iterations.....................: 300 10.0/s
vus............................: 10 min=10 max=10
vus_max........................: 10 min=10 max=10
关键指标说明:
-
checks
:
断言的成功率。例如,100.00% ✓ 600 ✗ 0
表示所有断言都成功。 -
data_received
和data_sent
:
测试期间接收和发送的数据量。 -
http_req_duration
:
每个 HTTP 请求的耗时,包括平均值(avg
)、最小值(min
)、最大值(max
)和百分位数(p(90)
、p(95)
)。 -
http_reqs
:
总请求数和每秒请求数(RPS)。 -
iterations
:
总迭代次数和每秒迭代次数。 -
vus
和vus_max
:
虚拟用户数和最大虚拟用户数。
案例分析
✗ status is 200
↳ 1% — ✓ 593 / ✗ 42328
checks.........................: 1.38% 593 out of 42921
data_received..................: 229 kB 1.3 kB/s
data_sent......................: 1.1 MB 5.9 kB/s
http_req_blocked...............: avg=41.93µs min=0s med=0s max=13.12ms p(90)=0s p(95)=245.5µs
http_req_connecting............: avg=36.97µs min=0s med=0s max=10.38ms p(90)=0s p(95)=208.3µs
✗ http_req_duration..............: avg=8.54s min=0s med=0s max=1m0s p(90)=59.99s p(95)=59.99s
{ expected_response:true }...: avg=16.04s min=13.34s med=16s max=19.07s p(90)=18.39s p(95)=18.79s
✗ http_req_failed................: 98.61% 42328 out of 42921
http_req_receiving.............: avg=495ns min=0s med=0s max=1.08ms p(90)=0s p(95)=0s
http_req_sending...............: avg=4.4µs min=0s med=0s max=2.5ms p(90)=0s p(95)=0s
http_req_tls_handshaking.......: avg=0s min=0s med=0s max=0s p(90)=0s p(95)=0s
http_req_waiting...............: avg=8.54s min=0s med=0s max=1m0s p(90)=59.99s p(95)=59.99s
http_reqs......................: 42921 238.456198/s
iteration_duration.............: avg=8.63s min=0s med=86.85ms max=1m0s p(90)=1m0s p(95)=1m0s
iterations.....................: 42921 238.456198/s
vus............................: 18 min=18 max=5000
vus_max........................: 5000 min=5000 max=5000
从提供的 K6 测试结果来看,系统的性能表现非常不理想,存在严重的性能问题。以下是对测试结果的详细分析:
1. 关键指标分析
**(1) **http_req_failed
- 值:
98.61% 42328 out of 42921
- 分析:
- 请求失败率高达 98.61%,说明绝大多数请求都失败了。
- 这是一个非常严重的问题,表明系统在高并发下无法正常处理请求。
**(2) **http_req_duration
- 值:
avg=8.54s min=0s med=0s max=1m0s p(90)=59.99s p(95)=59.99s
- 分析:
- 平均响应时间为 8.54 秒,最大响应时间达到 1 分钟。
- 90% 和 95% 的请求响应时间接近 60 秒,说明系统在高并发下响应极其缓慢。
- 这是一个明显的性能瓶颈,可能是由于服务器资源不足、数据库瓶颈或代码效率低下导致的。
**(3) **http_reqs
- 值:
42921 238.456198/s
- 分析:
- 总共发送了 42921 个请求,平均每秒发送 238.46 个请求。
- 虽然吞吐量看起来不低,但由于失败率极高,实际有效请求非常少。
**(4) **vus
和 vus_max
- 值:
vus: 18 min=18 max=5000
,vus_max: 5000 min=5000 max=5000
- 分析:
- 测试的目标是达到 5000 个并发用户,但实际只有 18 个虚拟用户在运行。
- 这表明系统在高并发下无法支持更多的虚拟用户,可能是由于资源耗尽或系统崩溃。
**(5) **checks
- 值:
1.38% 593 out of 42921
- 分析:
- 只有 1.38% 的请求通过了检查(状态码为 200)。
- 这与
http_req_failed
的失败率一致,进一步验证了系统的高失败率。
**(6) **data_received
和 data_sent
- 值:
data_received: 229 kB 1.3 kB/s
data_sent: 1.1 MB 5.9 kB/s
- 分析:
- 接收和发送的数据量较低,可能是由于请求失败率高,导致实际传输的数据量较少。
2. 问题总结
从测试结果可以看出,系统在高并发下存在以下问题:
- 极高的请求失败率(98.61%),表明系统无法处理高并发请求。
- 极长的响应时间(平均 8.54 秒,最大 60 秒),表明系统性能严重不足。
- 无法支持目标并发用户数(目标 5000,实际只有 18 个虚拟用户在运行),表明系统资源耗尽或崩溃。
常用脚本
测试一个 API 的性能,确定一下最高的并发数
通过逐渐增加压力的方式,进行压测
import http from 'k6/http';
import { check } from 'k6';
export let options = {
stages: [
{ duration: '30s', target: 1000 }, // 在 30 秒内逐步增加到 1000 个并发用户
{ duration: '1m', target: 5000 }, // 在 1 分钟内逐步增加到 5000 个并发用户
{ duration: '2m', target: 10000 }, // 在 2 分钟内逐步增加到 10000 个并发用户
],
};
export default function () {
let response = http.get('https://test-api.k6.io/public/crocodiles/');
check(response, {
'status is 200': (r) => r.status === 200, // 检查响应状态码
});
}
2、设置 Bearer Token
import http from 'k6/http';
export default function () {
// 设置 Token
const token1 = __ENV.API_TOKEN; // 使用 k6 run -e API_TOKEN=your_token script.js 传递 Token
//直接写入Token
const token = 'your_bearer_token_here';
const headers = {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json', // 根据需要设置其他请求头
};
// 发送请求
let response = http.get('https://test-api.k6.io/secure-endpoint', { headers: headers });
// 检查响应状态码
if (response.status !== 200) {
console.error('Request failed:', response.status, response.body);
} else {
console.log('Request succeeded:', response.body);
}
}
3、设置 Cookie
import http from 'k6/http';
export default function () {
// 设置 Cookie
const token = 'your_cookie_token_here';
const cookies = {
'session_token': token,
};
// 发送请求
let response = http.get('https://test-api.k6.io/secure-endpoint', { cookies: cookies });
// 检查响应状态码
if (response.status !== 200) {
console.error('Request failed:', response.status, response.body);
} else {
console.log('Request succeeded:', response.body);
}
}
4、 使用 SharedArray
加载用户列表
K6 的 SharedArray
可以高效地加载外部数据文件(如 JSON 或 CSV),并确保数据在多个虚拟用户之间共享。
示例:加载 JSON 文件
假设你有一个 users.json
文件,内容如下:
[
{"username": "user1", "userId": "101"},
{"username": "user2", "userId": "102"},
{"username": "user3", "userId": "103"}
]
在 K6 脚本中加载并使用这些数据:
import http from 'k6/http';
import { check } from 'k6';
import { SharedArray } from 'k6/data';
// 加载用户列表
const users = new SharedArray('users', function () {
return JSON.parse(open('./users.json'));
});
export let options = {
vus: users.length, // 设置虚拟用户数为用户列表的长度
iterations: users.length, // 每个虚拟用户只运行一次
};
export default function () {
// 获取当前虚拟用户对应的用户数据
const user = users[__VU - 1]; // __VU 是当前虚拟用户的 ID(从 1 开始)
const url = `http://https://test-api.k6.io/secure-endpoint?userId=${user.userId}`;
// 发送请求
let response = http.get(url);
check(response, {
'status is 200': (r) => r.status === 200, // 检查响应状态码
});
}
脚本说明
SharedArray
:用于加载用户列表,并确保数据在多个虚拟用户之间共享。vus: users.length
:设置虚拟用户数为用户列表的长度,确保每个用户对应一个虚拟用户。iterations: 1
:每个虚拟用户只运行一次,确保每个用户只被测试一次。__VU
:当前虚拟用户的 ID(从 1 开始),通过__VU - 1
可以获取用户列表中的对应数据。
5. 高级功能
-
分布式负载测试:
使用k6 cloud
命令将测试分布到多个节点,模拟更高并发。 -
生成 HTML 报告:
使用k6 run --out json=result.json script.js
生成 JSON 格式的测试结果,然后使用工具(如k6-to-junit
)转换为 HTML 报告。 -
集成 CI/CD:
将 K6 集成到 CI/CD 流水线中,自动化性能测试。 -
输出到influxdb中:
k6 run --out influxdb=http://localhost:8086/k6 script.js
总结
K6 是一款功能强大且易于使用的性能测试工具,适合测试 API、网站和后端服务的性能。通过 Chocolatey 可以快速安装 K6,使用 JavaScript 编写测试脚本,并通过丰富的指标分析测试结果。无论是开发、测试还是运维团队,K6 都能帮助您轻松实现性能测试目标。