性能压测工具选型实战:k6 vs JMeter vs Locust

性能压测不是上线前的走过场,而是用性能压测工具在真实流量放大之前,把系统的瓶颈、超时与内存泄漏提前暴露出来。无论是为了大促容量规划、发布前的回归压测,还是在容量红线逼近时做扩容决策,压测都是后端团队的刚需。k6、JMeter、Locust 是当前开发者圈最常被拿来对比的三款方案,但它们定位差异极大,选错会让压测本身变成负担:有人用 JMeter 去压一个简单接口,光搭 GUI 就花半天;也有人用 Locust 去压 JDBC,结果要自己造一堆轮子。

一、三款工具定位速览

一句话区分:k6 为开发者而生、脚本即代码;JMeter 是企业级 GUI 全能选手、协议覆盖最广;Locust 用纯 Python 写分布式压测,适合需要复杂逻辑编排的团队。需要强调的是,三者并非互斥——很多团队会同时保留 k6 做日常 CI 门禁、JMeter 做存量复杂协议回归,按场景各取所长。

维度k6JMeterLocust
脚本语言JavaScript (ES6)GUI/Java DSLPython
架构单进程 Go 引擎多线程 Java事件驱动协程
协议HTTP/gRPC/WS几乎全覆盖HTTP 为主
上手成本低(会 Python 即可)
最佳场景CI 门禁、接口压测企业级复杂协议自定义逻辑压测

二、k6:为开发者而生的代码化压测

k6 用 Go 编写引擎、用 JS 写脚本,天然适合塞进流水线。它最核心的两个概念是 check(单条断言,失败只记录不中断)和 threshold(阈值,不达标直接让脚本非零退出)。前者用来观察”哪些请求不健康”,后者用来当 CI 门禁——这是 k6 区别于另外两款的最大卖点:压测结果可以程序化判定,而不是人盯着报表。

import http from 'k6/http';
import { check, sleep } from 'k6';
import { Rate } from 'k6/metrics';

export const options = {
  vus: 50,
  duration: '30s',
  thresholds: {
    http_req_duration: ['p(95)<500'], // P95 必须 < 500ms
    http_req_failed: ['rate<0.01'],    // 错误率 < 1%
  },
};

export default function () {
  const res = http.get('https://api.example.com/orders');
  check(res, { 'status 200': (r) => r.status === 200 });
  sleep(1);
}

把压测接进 GitHub Actions 搭建的 CI/CD 流水线 后,阈值不达标就会让构建失败,相当于给每次发布加了一道性能红线。

2.1 在 CI 中跑 k6 阈值门禁

# .github/workflows/loadtest.yml
name: loadtest
on: [push]
jobs:
  k6:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Run k6 cloud/local
        uses: grafana/k6-action@v0.3
        with:
          filename: scripts/orders.js
        # 阈值未通过 → 步骤非零退出 → 流水线失败

三、JMeter:企业级 GUI 压测瑞士军刀

JMeter 的强项是协议覆盖面:HTTP、FTP、JDBC、JMS、SMTP 都能压,老系统里那些非 HTTP 的私有协议往往只有它能顶上。日常更推荐用 GUI 录制脚本、再用命令行无界面跑,避免 GUI 模式本身的 Swing 界面吃掉资源拖累数据。工程化时记得加三类元件:断言(Response Assertion 校验返回体)、CSV Data Set Config 做参数化(避免所有线程打同一个账号)、定时器(Constant Throughput Timer 控吞吐)。需要更大压力就开分布式,由一台 Controller 调度多台 Agent。

# 非 GUI 模式跑测试并生成 HTML 报告
jmeter -n   -t orders_test.jmx   -l result.jtl   -e -o report-html/

# 关键 JVM 调优(bin/jmeter 或 setenv)
export HEAP="-Xms4g -Xmx4g -XX:MaxMetaspaceSize=512m"

四、Locust:用 Python 写分布式压测

Locust 把”用户行为”建模成 Python 类,适合需要按业务流编排请求的场景。协程(gevent)模型让它用少量进程就能起上万并发,而且你能用真正的 Python 控制流写分支、循环、依赖前一步返回的数据——这是 JMeter 的 GUI 树很难优雅表达的地方。除了命令行,它自带一个 Web UI 实时看 RPS 和失败率,也能用 --headless 跑进 CI。复杂场景还能写自定义 load_shape 实现双十一式的脉冲流量。

from locust import HttpUser, task, between

class OrderUser(HttpUser):
    wait_time = between(1, 3)

    @task(3)
    def list_orders(self):
        self.client.get("/orders", name="GET /orders")

    @task(1)
    def create_order(self):
        self.client.post("/orders", json={"sku": "A1", "qty": 1})

# 分布式:master + 多个 worker
# locust -f order_locust.py --master
# locust -f order_locust.py --worker --master-host=10.0.0.1

五、怎么选:决策表

选型没有标准答案,关键看你的团队技能栈和压测目标。下面这张表把最常见的四种处境映射到首选工具,照着对号入座基本不会错;若团队同时具备 JS 和 Python 能力,k6 和 Locust 可以并行,JMeter 则留作存量复杂协议的兜底。

你的处境首选理由
想把压测塞进 CIk6脚本即代码、阈值门禁开箱即用
要压非 HTTP 老协议JMeter协议覆盖最广
压测逻辑很复杂LocustPython 表达力强、易复用
团队不会写代码JMeter纯 GUI 也能搭起来

六、压测指标到底看什么

新手容易只盯 RPS(每秒请求数),但 RPS 高不代表系统健康。真正该同时盯的是四组指标:虚拟用户数(VU,并发压力来源)、响应时间分位值(RT 的 P50/P95/P99,P99 才暴露长尾慢请求)、错误率(5xx/超时占比)、吞吐量(系统实际处理能力)。看分位而非平均值,是因为平均值会把 1% 的 3 秒慢请求稀释掉,而线上投诉往往就来自那 1%。

指标含义健康参考
VU并发虚拟用户随场景设定
P95 RT95% 请求耗时接口 SLA 内
P99 RT长尾耗时不超过 P95 的 2 倍
错误率失败请求占比< 0.1%
吞吐量系统真实处理力出现拐点即瓶颈

七、阶梯加压:别一上来就打满

很多压测翻车是因为”一开就是最大并发”,结果曲线直接塌方,分不清是应用还是压测机的问题。正确做法是阶梯加压(ramp-up):逐步抬升 VU,观察吞吐随压力变化的拐点。下面是 k6 的阶梯配置,从 0 慢慢加到 200 再回落,能清晰画出系统的容量曲线。

export const options = {
  stages: [
    { duration: '1m', target: 50 },   // 预热
    { duration: '3m', target: 200 },  // 阶梯加压
    { duration: '1m', target: 200 },  //  plateau 观察
    { duration: '1m', target: 0 },    // 降压回收
  ],
  thresholds: { http_req_duration: ['p(95)<500'] },
};

八、把压测接进可观测体系

压测孤军作战价值有限。把 k6 的 Prometheus 远端写打开,指标直接进 Prometheus + Grafana 监控面板,压测曲线和系统 CPU、QPS 同屏对照,瓶颈一目了然。若压出 502/504,可对照 Nginx 502/504 排查实录 从超时与连接池入手;压出数据库抖动则回看 MySQL 深度调优 的执行计划与参数。前端侧同样可参考 前端性能优化 Lighthouse 实战 做端到端收敛。

九、新手常踩的 4 个坑

现象解法
压测机先被打满自身 CPU 100%,曲线失真分布式起多台、监控压测机
只压单接口漏掉真实业务流按用户旅程编排请求
没有思考时间比生产更暴烈加 sleep/wait_time
不看服务端指标只盯 RPS联动监控面板看资源

十、小结

三款工具没有绝对优劣:要 CI 门禁选 k6,要复杂协议选 JMeter,要灵活逻辑选 Locust。真正重要的是把压测常态化、接进监控,让每一次发布都有性能兜底。建议从今天起就挑一款最顺手的,把团队核心接口写上压测脚本并挂进流水线——等下次大促或扩容评审时,你会感谢现在埋下的这条性能红线。

上一篇 Terraform 实战:用代码管理云基础设施
下一篇 WebSocket 实时通信实战:从轮询到双向推送