Grafana k6 性能测试完全指南:从入门到实践

一、什么是 k6?

k6 是一个现代化、开源、高性能的负载测试工具,由 Grafana Labs 维护,专为开发者和测试人员在 DevOps 时代进行性能测试而设计。它的核心设计理念是 "像单元测试一样做性能测试" (Like unit testing, for performance),旨在提供最好的开发者体验。

k6 最早起源于 2016 年,由 LoadImpact 团队开始打造一款"21 世纪开发者会喜欢的开源负载测试工具"。如今,k6 已经发展成为性能测试领域的重要工具,其社区也迅速壮大。

核心特性

k6 拥有一系列强大的特性,使其在众多性能测试工具中脱颖而出:

  • 可配置的负载生成:即使在配置较低的机器上,也能模拟大量流量。

  • 测试即代码:测试脚本可以复用、模块化、版本控制,并集成到 CI/CD 流水线中。

  • 功能完整的 API:脚本 API 功能丰富,帮助模拟真实的应用流量。

  • 嵌入式 JavaScript 引擎:拥有 Go 语言的执行性能,同时保留了 JavaScript 的脚本编写熟悉度。

  • 多协议支持:支持 HTTP、WebSocket、gRPC、Browser 等多种协议。

  • 丰富的扩展生态:可以通过扩展支持更多需求,社区已分享大量扩展。

  • 灵活的指标存储与可视化:支持将测试结果导出到各种后端服务。

  • 与 Grafana Cloud 原生集成:提供 SaaS 解决方案,支持测试执行、指标关联和数据分析。

为什么选择 k6?

k6 之所以受到广泛欢迎,主要得益于以下几个优势:

  1. 简单易用的 API 和 CLI:设计直观、灵活且强大。

  2. 使用 JavaScript 编写测试:开发者可以用熟悉的脚本语言构建真实的负载测试,复用模块和 JavaScript 库。

  3. 高性能:k6 引擎使用 Go 语言编写,是性能最佳的负载测试工具之一。

  4. 自动化测试:可将性能测试集成到 CI/CD 工具中,设置通过/失败标准,主动测试 SLO。

  5. 多后端输出:测试结果可以输出到 DataDog、Prometheus、NewRelic、Timescale 等多种后端。

  6. 轻松扩展:社区扩展支持 SQL、Browser、Kafka、Kubernetes、MQTT 等更多测试场景。

  7. 灵活的执行模式:可以在本地、分布式集群或 k6 Cloud 上运行相同的测试脚本。

k6 支持多种测试类型,包括冒烟测试、负载测试、压力测试、尖峰测试和浸泡测试等,能够满足不同场景下的性能验证需求。


二、环境搭建

2.1 安装 k6

k6 的安装非常简单,支持多种操作系统和平台。

macOS(使用 Homebrew):

bash

复制代码
brew install k6

Windows:访问 k6 官网下载安装包,双击安装即可。

Linux (Ubuntu/Debian)

bash

复制代码
sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys C5AD17C747E3415A3642D57D77C6C491D6AC1D6
echo "deb 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

bash

复制代码
docker pull grafana/k6

2.2 验证安装

安装完成后,在终端中执行以下命令验证是否安装成功:

bash

复制代码
k6 version

如果成功,会显示类似如下的版本信息:

text

复制代码
k6.exe v2.0.0 (commit/8c3be52cc1, go1.26.3, windows/amd64)

三、编写第一个测试脚本

k6 使用 JavaScript(ES6 语法)编写测试脚本。创建一个 .js 文件(例如 script.js),然后在其中编写测试逻辑。

3.1 基础 GET 请求测试

以下是一个完整的 GET 请求测试脚本:

javascript

复制代码
// 1. 导入需要的模块
import http from 'k6/http';   // 用于发送 HTTP 请求
import { check, sleep } from 'k6';  // check:验证响应;sleep:模拟用户思考时间

// 2. 测试配置
export const options = {
  vus: 5,           // 同时运行的虚拟用户数(并发数)
  duration: '10s',  // 测试持续时长
  thresholds: {
    http_req_duration: ['p(95)<500'],  // 95% 的请求响应时间小于 500ms
    http_req_failed: ['rate<0.01'],    // 请求失败率低于 1%
  },
};

// 3. 测试主逻辑——每个虚拟用户都会执行这里的代码
export default function () {
  // 发送 GET 请求(把 URL 换成你的接口地址)
  const res = http.get('https://api.example.com/hello');

  // 用 check 来校验响应是否符合预期
  check(res, {
    '状态码是 200': (r) => r.status === 200,
    '响应时间小于 500ms': (r) => r.timings.duration < 500,
  });

  // 暂停 1 秒,模拟真实用户的“思考”或“操作间隔”
  sleep(1);
}

3.2 代码解读

  • import:从 k6 内置库中引入所需模块。

    • http:用来发送 HTTP 请求(GET、POST 等)。

    • check:用于验证响应结果是否符合预期。

    • sleep:让脚本暂停执行,模拟用户的操作间隔。

  • export const options:测试配置项。

    • vus:虚拟用户数,即模拟的并发用户数量。

    • duration:测试持续时长。

    • thresholds:性能阈值,用于设定通过/失败标准。

  • export default function ():测试主逻辑,每个虚拟用户都会反复执行这里的代码。

  • http.get() :发起 GET 请求,返回的 res 对象包含状态码、响应体、耗时等信息。

  • check():检查响应是否满足条件,失败会记录在最终报告中。

  • sleep(1):暂停 1 秒后再执行下一轮循环。

3.3 常见接口测试场景

POST 请求(如登录、提交数据)

javascript

复制代码
const url = 'https://api.example.com/login';
const payload = JSON.stringify({
  username: 'testuser',
  password: 'password123',
});
const params = {
  headers: {
    'Content-Type': 'application/json',
  },
};
const res = http.post(url, payload, params);
需要 Token 认证的接口

javascript

复制代码
const params = {
  headers: {
    'Authorization': 'Bearer your_token_here',
    'Content-Type': 'application/json',
  },
};
const res = http.get('https://api.example.com/protected', params);
动态数据关联(如登录后提取 Token)

javascript

复制代码
// 发送登录请求,获得响应 res
const token = res.json('accessToken'); // 假设响应体为 {"accessToken": "..."}
// 在后续请求中使用提取的 token
const params = { headers: { 'Authorization': `Bearer ${token}` } };
http.get('https://api.example.com/profile', params);

四、执行测试

4.1 基本执行

在终端中切换到脚本所在目录,执行以下命令:

bash

复制代码
k6 run script.js

4.2 通过命令行参数调整测试规模

无需修改脚本文件,即可通过命令行参数灵活调整测试规模:

bash

复制代码
k6 run --vus 20 --duration 60s script.js

4.3 使用阶梯式负载(Stages)

通过 stages 配置可以模拟更真实的负载变化场景:

javascript

复制代码
export const options = {
  stages: [
    { duration: '2m', target: 50 },  // 2 分钟内爬升到 50 用户
    { duration: '5m', target: 50 },  // 保持 50 用户运行 5 分钟
    { duration: '2m', target: 0 },   // 2 分钟内逐步降为 0
  ],
};

这种配置逐步增加负载 → 保持稳定 → 平滑减少,能更真实地反映应用性能表现。


五、分析测试结果

5.1 终端摘要报告

测试运行结束后,k6 会在终端输出详细的测试报告,包含以下关键性能指标:

指标 说明
http_req_duration 请求的端到端响应时间
http_req_failed 失败请求的比例
http_reqs 每秒处理的请求数(RPS)
统计数据 平均值、中位数、最大值、最小值、p90、p95、p99 等百分位数

5.2 导出详细报告

  • 导出为 JSON 文件(方便后续分析):

    bash

    复制代码
    k6 run --out json=results.json script.js
  • 使用内置 Web Dashboard(实时图表):

    bash

    复制代码
    k6 run --web-dashboard script.js

    然后打开浏览器访问 http://localhost:5665 即可看到动态仪表盘。

  • 集成外部服务 :k6 支持将指标数据实时输出到 InfluxDBPrometheus 等时序数据库。

5.3 自定义报告(handleSummary)

通过 handleSummary() 函数,可以将结果导出为 JSON、HTML 等格式,便于存档和分享。


六、最佳实践

6.1 从冒烟测试开始

在正式进行大规模测试前,先用极小的负载(如 1 个 VU,持续几秒)运行脚本,确保脚本没有错误。冒烟测试可以验证:

  • 测试脚本是否没有错误

  • 系统能否处理最小的负载而不会出现问题

6.2 关注系统资源

监控运行 k6 的机器资源(CPU、内存),确保它不会成为测试的瓶颈。

6.3 版本控制

将测试脚本(.js 文件)纳入代码仓库(如 Git)进行管理,方便团队协作和版本追踪。

6.4 使用阈值(Thresholds)设定通过标准

阈值可以自动检查系统性能是否满足期望。例如:

  • 每个请求响应时间都小于 200ms

  • 小于 1% 的请求返回错误

一旦测试执行中不满足设定的阈值,测试就会以失败状态终止。

6.5 参数化测试数据

可以从 CSV 文件读取测试数据,实现参数化,模拟更真实的用户场景。


七、进阶功能

7.1 多协议支持

除了 HTTP,k6 还支持 WebSocket、gRPC 等协议。

7.2 浏览器测试

k6 的 Browser 模块支持在真实浏览器中执行测试,可以捕获前端性能指标。

7.3 AI 辅助测试

k6 v2.0 引入了 AI 辅助测试工作流、更广泛的 Playwright 兼容性以及新的断言 API。

7.4 扩展生态

k6 支持通过扩展来测试更多基础设施:SQL、Browser、Kafka、Kubernetes、Chaos、MQTT 等。

7.5 k6 Studio

如果不想编写代码,可以使用 k6 Studio 桌面应用来生成 k6 脚本。


八、总结

k6 是一款现代化、高性能、易于使用的开源负载测试工具。通过 JavaScript 脚本和高效执行能力,开发者可以创建全面的性能测试场景。

使用 k6 进行接口性能测试的流程清晰、上手简单:

  1. 安装:通过包管理器或 Docker 一键安装

  2. 编写脚本:使用 JavaScript 编写测试逻辑

  3. 执行测试 :通过 k6 run 命令运行

  4. 分析结果:查看终端报告或导出到可视化工具

无论你是初学者还是有经验的性能测试专业人员,k6 都能帮助你高效地完成性能测试工作,确保系统的可靠性和稳定性。