3. 压测工具选型:JMeter / Locust / 自研脚本

3.1 选型背后的逻辑

做 PKI SDK 压测,第一个难题往往不是怎么写脚本,而是选什么工具。

JMeter、Locust、自研脚本——这三条路我都走过。说实话,没有万能选项。每种工具都有自己的脾气,选错了后面折腾死你。我见过团队用 JMeter 去测 WebSocket 长连接,结果线程一多直接 OOM;也见过用 Locust 模拟几千个 CA 证书签发请求,把引擎跑崩了还不知道是工具瓶颈还是代码瓶颈。

所以这一章咱们不纸上谈兵。我会把实战中踩过的坑、对比的数据、还有最终选型的判断逻辑都掰开讲清楚。

3.2 JMeter:老牌大厂的选择

JMeter 是我最早接触的压测工具。Apache 出品,社区成熟,插件生态丰富。做 HTTPS/TLS 握手、证书验证这类 PKI 场景,JMeter 的 HTTP 取样器开箱即用。

优势:
  • GUI 界面直观,调试压测脚本方便 —— 团队新人上手快
  • 断言、参数化、定时器、监听器组件齐全,几乎不用写代码
  • 分布式压测支持成熟(Master/Slave 模式)
  • 丰富的报表(聚合报告、图形结果、JTL 日志)

但是,JMeter 的短板也明显。它基于 Java 线程模型,每个虚拟用户对应一个线程。线程多了之后,上下文切换开销会吃掉大量 CPU。我记得之前压测一个 OCSP 响应服务,并发到 3000 时,JMeter 自身 CPU 占用就飙到 80%,反而成了瓶颈。

而且,JMeter 的脚本是 XML 格式,团队协作时 diff 和版本控制非常痛苦。另一个痛点:写复杂业务逻辑(比如动态组装 PKCS#10 请求、解析 DER 编码的响应)需要写 Java BeanShell 或 JSR223 脚本,代码可维护性很差。

避坑指南: 我曾经用 JMeter 自带的 HTTP 取样器测试双向 TLS 认证,发现它默认不会发送客户端证书链。后来翻文档才知道要手动配置 SSL 管理器。类似这种 PKI 专有细节,JMeter 的抽象层太薄,稍不留神就漏配。

3.3 Locust:Python 系轻骑兵

后来项目转向 Python 生态,我开始用 Locust。它的核心思想是用协程(gevent)代替线程,单机就能拉起数千并发连接。对 PKI 场景来说,很多交互是 I/O 密集的(网络请求、加解密操作),协程模型正好匹配。

优势:
  • 编写测试场景就是写 Python 代码,灵活性远高于 JMeter
  • 协程并发,内存开销低,单机轻松上万虚拟用户
  • Web UI 实时查看 RPS、响应时间、错误率,调试体验好
  • 可以结合 PyCryptodome、cryptography 等库直接操作证书、密钥

但它也有坑。Locust 的分布式模式依赖 master/worker 通信,worker 数量多了之后,网络同步会引入延迟。我曾经试过用 8 台 worker 压测一个 CA 注册接口,结果 master 的 CPU 撑不住,大量请求超时——实际上是工具在丢包,不是服务扛不住。

另一个问题:Locust 的统计报表偏初级。没有 JMeter 那种按百分位、吞吐量趋势图细化分析的能力。需要自己写脚本把数据倒出来再画图。

我的建议: 如果你团队以 Python 为主、压测场景包含复杂证书组装或协议扩展,Locust 是首选。但别忘了提前测试分布式拓扑的极限。

3.4 自研脚本:最灵活但也最重

当工具无法满足需求时,自研脚本是终极武器。我做过的项目中,有两类情况必须自己写:

  • 专有协议:比如国密 SM2/SM3 的 TLS 握手、自定义的证书状态查询协议,JMeter 和 Locust 都不直接支持。
  • 极高精度控制:需要精确到微秒级的请求间隔、或者模拟真实客户端的重试/退避逻辑。

自研脚本的好处是:完全掌控链路,内存、线程、协程都自己管。我曾经用 asyncio + aiohttp 写了一个 CA 注册压测工具,单进程就能打满千兆网卡,RPS 跑到了 2 万以上,比 JMeter 同配置高 3 倍。

但代价也大:开发周期长,每换一个场景可能要大改。而且调试工具本身要花大量精力(连接池怎么管理、错误重试逻辑有没有 bug、数据采样是否准确)。我见过一个团队花了一个月自研压测工具,结果写出来的工具自己就有内存泄漏。

避坑指南: 自研脚本前先问自己三个问题:
1. 现有工具真的搞不定吗?
2. 团队有能力和时间维护这个工具吗?
3. 压测场景是否会频繁变化?
如果三个答案都是“是”,再动手;否则老老实实选现成工具。

3.5 三剑客横向对比

下面这张表是我在多次选型中总结的关键维度。你直接拿去用就行:

维度 JMeter Locust 自研脚本
学习成本 低(GUI拖拽) 中(需Python基础) 高(全栈开发)
并发模型 线程(Java) 协程(gevent) 自由选择
单机最大并发 ~3000(视CPU) ~10000+ 取决于实现
协议扩展性 一般(需Java插件) 好(Python原生) 最强
报表/分析 丰富 基础 自定义
分布式能力 成熟稳定 可用,有瓶颈 自己造轮子
PKI场景适配 需额外配置 配合密码库方便 随心所欲

3.6 我的选型建议

说了这么多,到底怎么选?我个人习惯用下面这个流程图来决策:

压测工具选型决策流程图 压测工具选型决策流程 开始:评估压测场景 团队熟悉Java / 插件生态吗? 是 否 选 JMeter 要求高并发 / 低资源? 是 否 选 Locust 有特殊协议/精度需求? 是 否 选 自研脚本 选 JMeter 说明: - 如果团队以Java为主且有现成JMeter插件,直接选JMeter最省事。 - 需要高并发且团队熟悉Python(如PKI SDK自动化脚本用Python编写),优先Locust。 - 遇到JMeter/Locust都搞不定的协议或精度要求,再投入资源自研。

你看这个流程:先问团队能力,再问性能需求,最后看特殊场景。我经历过多次选型后,总结出两条铁律:

  1. 能用现成工具就别自研。 即使自研性能更好,维护文档、社区支持、新人上手成本都是隐形成本。
  2. 压测工具越贴近业务语言越好。 比如我们用 Python 写证书生成逻辑,那 Locust 或自研脚本就比 JMeter 更自然。
我的习惯: 先在开发环境用 Locust 快速验证核心场景,确认无误后再决定是否上 JMeter 做长时间稳定性压测(因为 JMeter 报表更成熟)。这是个取巧的打法,但效果不错。