Artillery 负载测试入门:给 Node.js 应用做压力体检
Artillery 是 Node.js 生态主流的负载测试工具,用 YAML 声明流量模型;可达到的并发取决于脚本、压测机与部署方式。本文讲解测试脚本编写、多阶段加压、用户旅程模拟、CSV 数据驱动、插件扩展与 CI 集成。
Artillery 用一份 YAML 描述"每秒多少虚拟用户、执行什么请求流程",一条命令发起负载并输出延迟/吞吐量报告。核心价值是在流量高峰到来之前发现性能瓶颈——监控告诉你正在发生什么,负载测试告诉你将要发生什么。
监控之外的主动防线
监控和告警能反映当前状态,也可通过趋势或阈值提前预警。而大促、发布会这类可预见的流量高峰,正确的姿势是提前模拟:按代表性业务模型逐步增加测试流量,让瓶颈在测试环境暴露,而不是在生产环境爆炸。Artillery 就是这个场景下 Node.js 生态的标准工具。
安装与第一个脚本
npm install -g artillery
# load-test.yml
config:
target: 'http://localhost:3000'
phases:
- duration: 60
arrivalRate: 20 # 每秒 20 个虚拟用户
scenarios:
- name: '浏览首页'
flow:
- get:
url: '/'
artillery run load-test.yml
运行后输出每秒请求数、响应延迟分布(p50/p95/p99)、错误率——p99 延迟是衡量尾部体验的关键指标。
多阶段加压:模拟真实流量曲线
phases:
- duration: 120
arrivalRate: 10 # 预热:每秒 10 用户
- duration: 300
arrivalRate: 50 # 常规负载
- duration: 60
arrivalRate: 200 # 脉冲峰值
rampTo: 400 # 60 秒内爬升到 400
渐进加压能观察系统在不同负载区间的表现拐点:响应延迟在哪个负载区间开始非线性上涨,再结合错误率、资源饱和与压测机状态判断容量边界;arrivalRate 是每秒新建虚拟用户数,不是固定并发数。
用户旅程与数据驱动
真实用户不是打单一接口,而是走完整旅程:
config:
target: 'http://localhost:3000'
phases:
- duration: 10
arrivalRate: 1
payload:
path: 'users.csv'
fields: [username, password]
skipHeader: true
order: sequence
cast: false
scenarios:
- name: '注册登录下单'
flow:
- post:
url: '/api/register'
json:
username: '{{ username }}'
password: '{{ password }}'
- post:
url: '/api/login'
json:
username: '{{ username }}'
password: '{{ password }}'
capture:
- json: '$.token'
as: 'authToken' # 捕获响应用于后续请求
- post:
url: '/api/orders'
headers:
Authorization: 'Bearer {{ authToken }}'
users.csv 需提供表头和足够多的唯一测试账户,sequence 用尽会循环,分布式节点还可能重复使用数据;订单请求体须按接口补齐。CSV 提供用户名池,capture 提取登录令牌——多步骤、有状态的完整链路就此串起。需要随机数据时用 beforeRequest 自定义 hook 生成。
报告、插件与 CI 集成
artillery run --output report.json load-test.yml 生成 JSON 结果;artillery report 已在 2.0.22 移除,当前版本可保留 JSON 或使用 Artillery Cloud 报告。插件体系支持指标上报;expect 检查响应,ensure 对聚合指标设阈值并在不满足时以非零状态退出。CI 集成的典型姿势:部署到预发环境后跑冒烟负载,p99 超阈值即阻断发布。
让压测结果与服务端瓶颈对应
Artillery 的请求延迟升高时,要区分应用处理变慢与压测机自身饱和。把测试批次和服务版本写进应用日志,在观测云中对齐请求耗时、错误率、CPU 和事件循环延迟;服务端先接入 APM,业务指标通过可抓取的端点另行采集。用正常负载与高负载的同一条业务路径对照,才有依据判断该优化 SQL、扩容还是调整并发。
接入文档:Node.js APM 接入 · Prometheus 指标采集 · 监控器与告警策略。
常见问题(FAQ)
Q:Artillery 和 k6、JMeter 怎么选?
Artillery 基于 Node.js、支持 YAML 与 JavaScript 扩展,也支持分布式压测;k6 用 JavaScript 写脚本;JMeter 是 Java 工具,提供 GUI 与多种协议支持。按协议、脚本、分布式执行和团队运维条件实测选择,本文没有性能排名依据。
Q:压测会打垮生产数据库吗?
绝不要直接压生产。 在预发/测试环境压测,数据量级尽量逼近生产;必须压生产时需先协调授权、限制负载、设停止条件并监控;只读请求也可能耗尽共享资源。压测数据记得打标便于清理。
Q:虚拟用户数等于真实并发用户吗?
不等于。虚拟用户按脚本节奏发请求,真实用户有思考时间。换算关系取决于业务节奏——用生产访问日志的峰值 QPS 反推需要的 arrivalRate 更靠谱。
参考文档
本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。