31,698 颗星、9 年才发 1.0、现在到 v2.3.0:k6 把「性能测试」从 GUI 搬进了 CI

2025 年 5 月,Grafana 把 k6 推到了 v1.0——一个开源项目跑了 9 年才敢发的第一个大版本号。到 2026 年 9 月,它已经迭代到 v2.3.0,GitHub 上是 31,698 颗星、1,651 个 Fork、772 个 open issues,AGPL-3.0 许可。这个数字组合本身就有意思:星数在涨,但 issues 也没有被”清空”。它是一个正在被大量生产环境使用、同时仍在快速演进的项目。

k6 的自我定位是”就像单元测试,只不过测的是性能”。它不是把 JMeter 翻译一遍,而是换了一套哲学:测试即代码。你用 JavaScript(v1.0 起支持原生 TypeScript,写好 .ts 直接 k6 run script.ts,不需要转译)描述用户行为,脚本进 Git、进 Code Review、进 CI/CD,而不是塞在一个 XML 里点来点去。

它到底解决什么问题

传统压测的三个痛点,k6 逐个回应:

  1. 脚本不可维护。JMeter 的 .jmx 是 XML,Git diff 基本没法看。k6 是纯 .js 文件,diff 友好,能复用现有 JS/TS 代码和类型。

  2. 资源效率。k6 用 Go 作为运行时,每个虚拟用户(VU)是 goroutine,不是操作系统线程。对比 JMeter 的 thread-per-VU 模型,同样压力下 k6 的内存占用可以低一个数量级——一台普通机器就能模拟出可观的并发,而不需要先摆一排压测机。

  3. 压测和流水线脱节。k6 的杀手锏是声明式阈值(thresholds)。写一句 http_req_duration: ["p(99) < 3000"],一旦违反,k6 直接以非零码退出,CI 里不需要再写任何解析脚本就能让 PR 挂掉。这一条,是它在 CI/CD 场景里碾压式胜出的核心原因。

一个最小的例子就能看懂它的风格:

import http from "k6/http";
import { check, sleep } from "k6";

export const options = {
  thresholds: { http_req_duration: ["p(99) < 3000"] },
  stages: [
    { duration: "30s", target: 15 },
    { duration: "1m", target: 15 },
    { duration: "20s", target: 0 },
  ],
};

export default function () {
  const res = http.get("https://quickpizza.grafana.com");
  check(res, { "status was 200": (r) => r.status == 200 });
  sleep(1);
}

v2.x 这条线现在在补什么

从 v1.0 到 v2.3.0,k6 的重点从”能不能用”转向”用得顺不顺”。

v1.0 确立了三件事:语义化版本(破坏性变更只在大版本出现,且提前弃用警告)、每个大版本至少 2 年关键修复、以及明确划出公开 API 面,让扩展生态有稳定基石。同时 k6/browser、k6/net/grpc、k6/crypto 三个模块正式从实验转正。

v2.1.0 引入特性开关系统(--features / K6_FEATURES / k6 features 发现命令),第一个开关是实验性的原生直方图。v2.2.0 做了件很实用的事:k6 cloud run --local-execution 现在把日志也流到 Grafana Cloud,本地跑也能在云端看日志;还加了 chromium.connectOverCDP(),可以附着到已经跑起来的 Chromium(对标 Playwright 的同名能力)。v2.3.0 则有 --scenario 只跑脚本里的某个场景、--once 把压测脚本当烟囱/功能测试用,以及跨 await 依然能正确归组的异步 group()。

值得一提的是浏览器测试线:k6 的 browser 模块 API 刻意向 Playwright 靠拢,支持真实的 Chromium、Web Vitals 指标、截图和 Browser Timeline。也就是说,它不只是压接口,还能压”真实用户打开页面”这条链路。k6 Studio 2.0 也在 2026 年 8 月补上了录制器,让不喜欢手写脚本的人有了入口。

边界在哪:它不做什么

必须说清楚,k6 不是万能压测器。

协议覆盖比 JMeter 窄。 它原生支持 HTTP/HTTPS、WebSocket、gRPC、浏览器。但 JDBC、JMS、LDAP、FTP、老式 SOAP 这些,k6 没有原生采样器——需要靠 xk6 扩展生态去补,而这些扩展的维护质量参差不齐。

没有图形界面。 官方的做法是把可视化交给 Grafana 生态:本地跑输出统计摘要,或把指标推到 Prometheus/Grafana Cloud 看趋势。习惯”点着鼠标建测试计划”的团队,第一天会不适应。

分布式能力绑定商业路径。 要多机分布式压测,最顺的路径是 Grafana Cloud k6(有每月免费额度,Pro 大约按 VU-hour 计费)或者用 k6 Operator 跑在 Kubernetes 上。想完全自建大规模分布式,得自己搭一套,不轻松。

JS 运行时不是 Node.js。 它用的是 Goja 解释器,npm 包不能直接 import——这也是很多人第一次上手时最容易踩的坑。

真实使用门槛与适合谁

门槛其实不低,只是门槛类型变了:它把”学工具”的成本,换成了”写代码”的成本。你团队里得有人愿意用 JS/TS 写测试、维护脚本、看得懂 p99 和吞吐曲线。

  • 适合:以 HTTP/gRPC/WebSocket API 为主的后端团队;团队本来就写 JS/TS;希望把性能门禁嵌进 CI,让 PR 阶段就暴露回归;已经在用 Grafana/Prometheus 做可观测性。
  • 不适合:需要测数据库/消息中间件/老式企业协议且不接受扩展的团队;完全没有开发人力、纯靠测试工程师点界面的组织;需要覆盖 SAP、Oracle 这类打包系统(k6 和 JMeter 都覆盖不了,得看 WebLOAD 这类商业工具)。

下一步可以怎么做

如果你手上有一个跑在 K8s 里的 HTTP 服务,最快验证路径是:装好单文件二进制 → 复制上面那段脚本改成你自己的接口 → 本地 k6 run 跑一次拿到 p95/p99 基线 → 把 thresholds 写进脚本 → 挂进 CI,让它在每次 PR 上跑 1 分钟轻量档。等你确认”它能听懂你的业务”之后,再去考虑 Grafana Cloud 或 k6 Operator 做规模化。

参考链接:

评论区

0 条评论

登录后可评论。

拾光·开源拾遗 2168 阅读