Artillery 是一个开源的 Node.js 负载测试工具包,它可以通过一个简单的 YAML 脚本向你的 API 发起高并发流量。你可以定义负载阶段和请求流程,运行 artillery run script.yml,然后读取延迟百分位数、请求速率和错误数。本指南将引导你安装 Artillery v2、编写真实的测试脚本、运行测试、以当前的 v2 方式捕获结果,并将其集成到 CI 中。
什么是 Artillery 以及何时使用它
Artillery 会生成虚拟用户(VU)来访问你的接口,并衡量系统在持续流量下的承载能力。虚拟用户是一个模拟的客户端,它会像真实的调用者一样,依次执行一个场景中的每一个请求。
当你需要解决扩缩容和性能瓶颈问题时,就可以使用 Artillery。例如:在每秒 50 次请求的情况下,p95 延迟表现如何?在什么到达率(arrival rate)下开始出现错误?API 在持续负载五分钟内能否保持稳定,还是会发生降级?
Artillery 在这方面表现出色,因为其测试是声明式的。你在 YAML 中描述负载形态,而无需手动编写并发循环代码。它可以在任何运行 Node.js 的地方运行,因此相同的脚本既可以在你的笔记本电脑上运行,也可以在 CI 中运行。
Artillery 是该领域众多选择之一。如果你还在对比工具,这篇 top load testing tools roundup 和这篇 load testing software comparison 涵盖了 k6、JMeter、Gatling 等工具之间的权衡取舍。
安装 Artillery (v2)
包名正是 artillery,当前的重版本是 v2。使用 npm 全局安装它,然后验证版本。
npm install -g artillery@latest
artillery version
你需要安装最新的 Node.js LTS 版本。Artillery 支持在 Windows、macOS 和 Linux 上运行。
如果你不想全局安装任何东西,可以使用 npx 按需运行。
npx artillery@latest run script.yml
编写 Artillery 测试脚本
Artillery 测试是一个包含两个顶级部分的 YAML 文件。config 部分定义了目标和负载特征。scenarios 部分定义了每个虚拟用户的操作。
以下是一个完整的脚本,它会进行预热、爬升至峰值,然后保持持续的负载。
config:
target: "https://api.example.com"
phases:
- name: "Warm up"
duration: 60
arrivalRate: 5
- name: "Ramp to peak"
duration: 120
arrivalRate: 5
rampTo: 50
- name: "Sustained load"
duration: 300
arrivalRate: 50
maxVusers: 500
# Inline variables (or use a CSV via config.payload)
variables:
productId:
- "1001"
- "1002"
scenarios:
- name: "Browse and create order"
flow:
- get:
url: "/v1/products/{{ productId }}"
- post:
url: "/v1/orders"
json:
productId: "{{ productId }}"
quantity: 2
理解 config 部分
config.target 是每个请求运行的基础主机。测试场景中的每个步骤都会将其 url 追加到这个基础主机后面。
config.phases 是一个按顺序运行的负载阶段数组。你最常用的键包括:
duration:阶段持续的时间,以秒为单位,或使用易读的字符串(如"5m")。arrivalRate:每秒启动的新虚拟用户数量。rampTo:在整个阶段中,将到达率从arrivalRate线性提升至该值。arrivalCount:在整个阶段中分配的固定虚拟用户数,而不是每秒的速率。maxVusers:并发运行的虚拟用户数量上限。name:显示在输出中的标签。
有一个细节容易让人混淆。阶段的 duration 控制的是 Artillery 持续生成虚拟用户的时间,而不是测试的总实际时间。如果一个虚拟用户在阶段即将结束时启动,且其测试场景需要执行一段时间,那么测试运行将继续进行,直到该用户执行完毕。
理解 scenarios 部分
scenarios 是一个数组。每个测试场景都包含一个 flow,即虚拟用户运行的有序步骤列表。可选的键包括 name 和 weight(权重),其中 weight 设置了 Artillery 为特定虚拟用户选择该测试场景的相对概率。
Flow 步骤使用 HTTP 动词键:get、post、put、delete 和 patch。每个步骤都接受一个 url,请求 body 则放在 json 下。双大括号语法 {{ productId }} 用于引入变量。
从 CSV 文件驱动请求
对于冒烟测试来说,硬编码数值是可以的。但为了模拟真实的负载,可以通过 config.payload 从 CSV 文件中读取数据。每个虚拟用户会选择其中的一行,列名则会转换为变量。
config:
target: "https://api.example.com"
payload:
path: "./users.csv"
fields:
- "email"
- "password"
phases:
- duration: 120
arrivalRate: 20
scenarios:
- flow:
- post:
url: "/login"
json:
email: "{{ email }}"
password: "{{ password }}"
运行测试
基础命令会将 Artillery 指向你的脚本。
artillery run script.yml
# Override target without editing the script:
artillery run --target https://staging.example.com script.yml
# Pass variables as JSON:
artillery run -v '{ "productId": ["1001","1002"] }' script.yml
有几个命令行标志值得了解。--target(或 -t)会覆盖 config.target,以便你可以将同一个脚本指向测试环境或生产环境。--environment(或 -e)用于选择 config.environments 下的命名配置块。--config(或 -c)从单独的文件加载配置。--insecure(或 -k)用于在测试环境中跳过自签名证书的 TLS 验证。
查看结果
在测试运行期间,Artillery 大约每 10 秒会打印一次聚合指标。测试完成后,你将获得一份总结报告。其中最重要的指标包括:
- 请求速率:运行实际达到的每秒请求数。
- 延迟百分位数:p50(中位数)、p95 和 p99 响应时间。p95 反映了最慢的 5% 请求的体验,这通常是问题最先显现的地方。
- 错误计数:失败的请求、超时以及非 2xx 响应,按类型分组。
关注尾部延迟,而不仅仅是平均值。平均值可能看起来很正常,但 p99 却在悄悄爬升到数秒之久。如果错误仅在持续阶段出现,那么你很可能找到了一个值得调查的饱和点。关于要追踪哪些指标以及原因的更深入探讨,请参阅这篇 API 性能测试指南。
在 Artillery v2 中生成报告
不同版本的 Artillery 中报告功能有所变化,因此过时的教程很容易误导你。旧指南会告诉你运行 artillery run --output report.json,然后再运行 artillery report report.json 来生成 HTML 文件。前半部分仍然有效,但后半部分已经不行了。
--output 参数仍然会写入机器可读的 JSON 结果文件。
# Write machine-readable JSON results (still supported):
artillery run --output report.json script.yml
artillery report 命令(即 JSON 到 HTML 的生成器)已从 Artillery CLI 中移除。官方文档指出它“不再受支持,且已从 Artillery CLI 中移除”。HTML 报告代码因无人维护而被弃用,随后被彻底移除,并且没有重新引入的计划。不要运行 artillery report report.json;它在当前的 v2 版本中无法工作。
相反,你现在有以下三种选择。
第一,自己解析 JSON。这非常适合 CI 环境,因为你可能需要针对阈值进行断言。使用 jq 提取聚合的 p95 延迟:
jq '.aggregate.summaries["http.response_time"].p95' report.json
第二,使用 Artillery Cloud 云端托管的仪表盘。这是旧版 HTML 报告的官方替代方案。运行命令时传入 --record 和你的 API key。
artillery run --record --key $ARTILLERY_CLOUD_API_KEY script.yml
第三,使用 publish-metrics 插件或 OpenTelemetry 将指标推送到你自己的监控技术栈中,这样延迟和错误率就会直接呈现在你已用于生产环境的相同仪表盘上。
在 CI 中运行 Artillery
由于 Artillery 只是一个 Node.js CLI,因此它可以轻松嵌入到任何流水线中。以下是一个 GitHub Actions 工作流,它会安装 Artillery、运行测试,并将 JSON 报告上传为构建产物。
name: Load test
on: [workflow_dispatch]
jobs:
artillery:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: "lts/*"
- run: npm install -g artillery@latest
- run: artillery run --output report.json script.yml
- uses: actions/upload-artifact@v4
with:
name: artillery-report
path: report.json
此示例通过手动触发运行。由于重度压力测试需要耗时数分钟并消耗实际带宽,因此通常是按需或通过定时任务触发,而不是在每次提交时都运行。一旦生成了 JSON 报告,你可以添加一个 `jq` 步骤,在 p95 超过设定指标时使该任务失败。
## Apifox 的定位:功能测试与 CI 门禁
Artillery 解答的是“API 能否承受得起如此大的流量?”这是负载与性能测试。与此同时,还有一个截然不同的问题:“在代码修改后,API 是否依然返回正确的响应?”这就是功能测试和回归测试的范畴,也正是 [Apifox](https://apifox.com/?ref=apifox.com) 的用武之地。
Apifox 是一个集设计、调试、mock、文档和自动化测试于一体的全流程 API 平台。它的测试场景将接口分组为包含 if、for 和 foreach 等条件的逻辑步骤,以便你可以校验响应 body、状态码和数据契约。你可以在 CI 中通过 Apifox CLI 运行这些测试场景,以便在代码修改后对合并请求进行准入拦截。
请明确两者的界限。Apifox 确实包含了性能测试功能,但其最大支持 100 个虚拟用户。这足以发现明显的回归问题,但并不能在高并发场景下替代 Artillery。对于大规模、分布式、基于代码建模的负载测试,Artillery 才是正确的工具。在我们关于“不用 Python 进行 API 压力测试”的文章中也提到了这一坦诚的定位,而 Apifox 100 个虚拟用户功能的具体机制可以在《Apifox 中的 API 性能测试》中找到。
因此,建议结合使用这两者。使用 Artillery 进行大规模负载测试;在 CI 中使用 Apifox CLI 运行功能测试和回归检查,以便在发布前发现异常行为。
Apifox CLI 可通过 npm 安装,且 `apifox run` 仅支持使用参数标志(flag-only)。
bash
Apifox CLI: functional/regression run in CI (flag-only, no positional file)
npm install -g apifox-cli apifox run \ --access-token $APIFOXACCESSTOKEN \ -t\ -e\ -r cli,junit \ --out-dir ./apifox-reports ```
-t 标志是测试场景 ID,-e 是必需的环境 ID,而 -r cli,junit 会同时输出控制台结果和 CI 系统可读取的 JUnit XML 报告。有关逐步的操作指南,请参阅 Apifox CLI 教程;有关流水线设计模式,请参阅这些“API 测试的 CI/CD 最佳实践”。
想要在运行 Artillery 负载测试的同时,通过功能测试和契约测试来规范你的 CI 准入吗?免费下载 Apifox 并构建你的第一个测试场景吧。
常见问题解答
什么是 Artillery 负载测试?
Artillery 负载测试是指使用开源的 Artillery 工具包来模拟大量并发虚拟用户请求你的 API。你可以在 YAML 脚本中描述负载模型和请求流并运行它,然后通过测量延迟百分位数、请求速率和错误率,来观察你的系统在压力下的表现。
Artillery 是免费且开源的吗?
是的。Artillery CLI 核心是免费且开源的,以 artillery 包的形式在 npm 上分发。此外,还有一个付费的托管服务 Artillery Cloud,它提供了一个展示结果的仪表盘,但即使没有它,你也可以在本地和 CI 中运行完整的负载测试。
如何运行 Artillery 负载测试?
使用 npm install -g artillery@latest 进行安装,编写一个包含 config 块(目标和阶段)和 scenarios 块(请求流)的 YAML 脚本,然后运行 artillery run script.yml。Artillery 会每 10 秒打印一次实时指标,并在结束时输出一份总结。
如何生成 Artillery 报告?
运行 artillery run --output report.json script.yml 以写入 JSON 结果文件。旧的用于生成 HTML 的 artillery report 命令已从 CLI 中移除。相反,你可以使用类似 jq 的工具来解析 JSON,通过 --record --key 使用 Artillery Cloud,或者使用 publish-metrics 或 OpenTelemetry 插件推送指标。
Artillery 对比 k6 或 JMeter:应该选择哪一个?
这三者都能处理大规模的负载。Artillery 使用声明式 YAML 和 Node.js,非常适合已经融入 JavaScript 生态系统的团队。k6 使用 JavaScript 编写脚本,采用代码优先模式。JMeter 是由 GUI 驱动且基于 Java 的,拥有悠久的插件历史。Gatling 与 JMeter 的对比更深入地探讨了这些权衡。选择脚本编写模式契合你团队的工具,然后将其与 CI 中的功能测试结合使用,以实现完整覆盖。
开发必备:API 全流程管理神器 Apifox
介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档、调试、设计、测试、Mock、自动化测试于一体的工具,Apifox 是目前提升研发效率的首选。
如果你正在开发项目,不妨试试其极其友好的界面设计,它完全兼容 Postman 和 Swagger 数据格式,导入数据非常方便,,即使是新手也能很快上手,点击这里即可注册使用。

值得一提的是,除了个人和常规团队使用,针对有高安全合规要求、或需要在内网环境协作的企业,Apifox 还提供了深度定制的私有化部署方案。
获取专属报价与部署方案
详细的私有化部署系统架构与安全白皮书
针对您公司规模的专属报价单
免费的 1v1 专属产品演示 (Demo) 机会