开源负载测试工具评估
说来有意思,进上家公司的第一件事是做些技术工具调研(居然不是还技术债,后来证明我还是拿衣服了),虽然最后也只是做了个 PoC 演示,并没有实际在生产环境使用,不过整个过程还是值得记录一下的。
关于测试,其实和一直以来的工作内容还是有不少交集的。
就 SRE (Site Reliability Engineer) 而言,需要通过测试来发现系统和平台的性能瓶颈,以防患于未然。对 DevOps 而言,在构建 CI/CD Pipeline 时,需要集成自动化测试,理想情况下,可能会包括单元测试 / 功能测试 / 集成测试 / 安全测试 等等。
比如更早一点,大概 12 年的时候,当时部门调研流处理框架 (Stream Processing Frameworks),使用 Twitter Storm(后来改名 Heron,并在 18 年捐献给 Apache,当然现在 Flink 是大趋势了)。想在生产环境使用,但当时文档并不多,所以读完核心代码后,就主攻负载和压力测试了。
等等,好像暴露了。不能丢人,补救一下:人在新西兰,没搞过大数据。
言归正传。以下正文,Enjoy:
评估标准
技术范围
- 是否具有测试公司核心模块的能力
- 是否支持主要协议和复杂场景
性能 / 测量精度
- 是否稳定且性能良好
- 能否准确测量目标系统的响应时间
人气 / 趋势
- 文档是否规范,是否有良好的社区或专业支持等
- 对开发人员是否友好,包括用哪种语言编写 / 可支持的扩展语言等
操作 / 可维护性
- 使用方便,易于上手
- 运营维护成本
- 是否跨平台且易于扩展
- 是否有带图形的测试报告
- 是否基于 Cloud( SaaS 或云托管能力)
成本
- 费用:免费 / 一次性费用 / 按月或按年付费 等等
集成 / 自动化
- 是否支持自动化
- 是否方便与公司技术栈集成,作为 CI / CD 工具链的一部分(如 Maven / Jenkins / Bamboo 等)
测试工具
在评估市场中的工具时,有些不适合公司内部需求,有些仅限于 HTTP 协议,还有些也有多年没有更新了。不少工具都不够灵活,无法提供比如参数化,断言和分布式测试的功能。
所以,基于上述的评估标准,选出了下面几个工具来具体对比和分析:
- Apache JMeter
- Locust
- Gatling
- K6 (from LoadImpact)
- Apachebench
- Artillery
- Hey (previously "Boom")
- Siege
- Tsung
- Wrk
- The Grinder
- Taurus (from BlazeMeter)
同时基于成本考虑,评估的工具都是开源的。与商业应用相比,基本可以满足测试的技术要求和功能。
当然也可以选择商业软件,比如 LoadImpact / BlazeMeter / Loadrunner / NeoLoad 等等。
另外,国内大公司也有自己的测试产品。
比如阿里云有「性能测试 PTS」,腾讯也有测试中台「WeTest」:
Benchmark
Benchmark 阶段,不同工具在同一测试场景下的测试数据可能也会有较大差异。
所以,对工具进行基准测试对比(性能,稳定性和数据准确性等方面)还是很有必要的。
一开始是探索阶段。使用手工测试,把玩了不同工具,使用不同参数(比如 并发数 / 虚拟用户数 VUs,线程数等等),以便有个大概的感受。
准备基准对比时,尝试尽可能地使用相似的参数来跑这些工具。不过,让所有工具使用完全相同的参数是不大现实的,因为它们有不同的操作模式,对应在这些工具中,其工作方式也是不尽相同的。
所以下面针对不同的并发数来进行测试比较(暂时不考虑网络时延等情形),来得出一个粗精度的数据:
-
该测试工具可以产生的最大 RPS 是多少
-
使用工具额外引入的延迟有多少
以下的测试,是运行在 Docker 环境里的。
关于容器化与性能,值得注意的是,如果在 Docker 容器内运行基准测试的话,和直接在目标机器运行测试工具相比,每秒请求数(RPS)大概会降低 40% 左右。
所以下面的测试数据,和跑原生工具相比会偏低。
RPS rates (different VU levels) Average Reponse times最终,基于以上的探索把玩和基准测试,工具的整体对比如下:
总结
个人会比较推荐 Gatling,备选方案是 Locust / JMeter,同时对 K6 保持观望。
主要是基于以下几个方面考虑:
-
Gatling:性能和文档非常好。基于 Scala,使用 DSL(领域特定语言)。使用优秀的图表库Highcharts 自动生成基于 Web 测试结果可视化。另外,可以轻松与 CI 集成,因为有断言。可以指定测试结果的目标要求(错误率,响应时间等)。虽然本身不支持分布式,但有 workround。来自 Locus 的作者的 这篇文章 解释了为什么觉得 Gatling 和 Locust 相比,可能是更好的选择。
-
Locust:酷就一个字,我只说一次。为开发人员而生,允许编写 Python 代码。不过,在负载生成能力和测量精度方面的是个很大的短板。在基准测试中,比最快的工具慢大约 25 倍,因为仅使用单个 CPU。在测试机器上差不多可达到 500-600 RPS,不过如果启动多个 Locust 进程并以分布式模式运行的话,可能会达到 2000-2500 RPS。
-
K6:新秀,感觉更现代化一些。用 Go / JavaScript 编写,提供自动化友好的脚本 API,标准化输出格式,适用于CI / CD 自动化。从上面图表看,性能还是相当不错的。
-
Grinder:看起来挺古老,感觉半死不活的项目(发布时间是 2000 - 2012 年),还是在Sourceforge 上托管。使用 JPython 并提示脚本 API。使用后发现,还算是一个比较灵活和称职的工具,性能表现良好。后来有了解到,国内还是有些一二线公司会基于这个框架做些定制化。
-
Tsung:Erlang编写,支持多种不同的协议。旨在提供可扩展性和性能。主要缺点是使用 XML编写用户场景,和 Jmeter 一样。总的来说,功能是有的,但可用性一般。
-
Artillery:不错的命令行界面,提示自动化支持,但是性能较低,同时缺乏脚本编写能力。在测试基准击败了 Locust,但不支持分布式。
-
ApacheBench:如果只需要点击一个 URL 而不需要测试其他,那就 ab 没跑了。但也几乎不会做其他任何事情了。
-
Vegeta:专注于固定速率测试,比如 API endpoint 自动测试。
-
Wrk:表现很不错。如果想从单机生成最大流量,而不太关心详细的结果指标,同时模拟的流量不是很复杂的话,就它没错了。它可以复制相同的请求并在 http 管道中发送出去。在这种情况下,可以在单核 CPU上每秒生成数百万个请求。可以在 这里 找到示例。不过 Wrk 通过使用 Lua 编写脚本,而不是Python,其基于回调的 API 也比不上 Locust 的。
-
JMeter:非常称职的工具。和其他开源的负载测试工具相比,它具有更多功能和集成,以及更广泛的用户群。可以测试多种不同的协议,提供了良好的性能和可扩展性。不过,个人感觉主要的负面因素是对用户不友好。因为其配置,包括用户场景逻辑,都是用 XML 编写的。不过 这里 提供了一个允许编写脚本的 Ruby DSL。但也正因为如此,给一些商业工具提供了机会。比如 Blazemeter 。
-
Taurus:为持续测试提供了一个自动化友好的框架,可支持 Gatling,Jmeter 和 Locust 等作为其底层测试工具。
Metrics
示例:Gatling - HTML 格式的测试报告
示例:Locust
示例:K6 + InfluxDB + Grafana
结尾
也是没谁了,把自己写的英文文档捯饬了一下,去粗取精又翻译了回来。
容易么我?Google Translate 如是说。
非专业测试人员,还望各位大佬轻拍。
同时也欢迎在文章里留言或进群交流。
[往期精彩]