npm包autocannon牛逼的后台压力测试库
什么是autocannon?
autocannon是Node.js生态中最强大的HTTP/1.1基准测试工具之一,它具有以下核心优势:
- 轻量高效:纯JavaScript实现,无需额外依赖
- 精准控制:支持毫秒级精确的请求速率控制
- 丰富指标:提供完整的延迟分布统计和实时监控
- 灵活部署:既可作为CLI工具快速测试,也能通过API集成到CI/CD流程
注:
HTTP/1.1 版引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求,进一步改进了 HTTP 协议的效率
但这要求服务端必须按照请求发送的顺序返回响应,当顺序请求多个文件时,其中一个请求因为某种原因被阻塞时,在后面排队的所有请求也一并被阻塞,这就是队头阻塞 (Head-Of-Line Blocking)
多拓展一点:HTTP/2 服务有更先进的 multiplexing (多路复用的技术)机制(在https下支持)
javascript//我们可以使用Axios来发送HTTP请求并配置http2选项 import axios from 'axios'; axios({ method: 'get', url: 'https://example.com/api/data', http2: true, // 启用http2协议 }) .then(function (response) { // 请求成功后的处理 }) .catch(function (error) { // 请求失败后的处理 });
安装与基本使用
安装方法
bash
npm install -g autocannon
# 或作为项目依赖
npm install autocannon --save-dev
基本测试命令
arduino
autocannon -c 100 -d 20 http://localhost:3000
这条命令会:
- 模拟 100 个并发连接
- 持续测试 20 秒
- 针对
http://localhost:3000
进行压力测试
测试 POST 请求
json
autocannon -m POST -H "Content-Type: application/json" -b '{"username":"test"}' http://localhost:3000/login
完整参数详解(按功能分类)
1. 连接控制参数
参数 | 缩写 | 类型 | 默认值 | 说明 |
---|---|---|---|---|
--connections |
-c |
NUM | 10 | 并发连接数 |
--pipelining |
-p |
NUM | 1 | 每个连接的流水线请求数 |
--socketPath |
-S |
PATH | - | UNIX域套接字路径 |
--workers |
-w |
NUM | - | 工作线程数 |
--maxConnectionRequests |
-M |
NUM | - | 每个连接最大请求数 |
--maxOverallRequests |
-O |
NUM | - | 总体最大请求数 |
最佳实践:
bash
# 使用100个连接,每个连接pipelining 5个请求
autocannon -c 100 -p 5 http://localhost:3000
2. 时间控制参数
参数 | 缩写 | 类型 | 默认值 | 说明 |
---|---|---|---|---|
--duration |
-d |
SEC | 10 | 测试持续时间(秒) |
--amount |
-a |
NUM | - | 总请求次数(覆盖duration) |
--timeout |
-t |
SEC | 10 | 请求超时时间 |
--warmup |
-W |
- | - | 预热参数 |
示例:
bash
# 运行30秒测试,前5秒预热
autocannon -d 30 -W "-c 1 -d 5" http://localhost:3000
3. 请求配置参数
参数 | 缩写 | 类型 | 默认值 | 说明 |
---|---|---|---|---|
--method |
-m |
METHOD | GET | HTTP方法 |
--body |
-b |
STRING | - | 请求体 |
--form |
-F |
JSON | - | 表单数据 |
--input |
-i |
FILE | - | 请求体文件 |
--headers |
-H |
K=V | - | 请求头 |
--har |
- | FILE | - | HAR文件导入 |
复杂请求示例:
json
autocannon -m PUT \
-H "Authorization: Bearer token" \
-H "X-Request-ID: 123" \
-b '{"update":"value"}' \
http://localhost:3000/api
4. 速率控制参数
参数 | 缩写 | 类型 | 默认值 | 说明 |
---|---|---|---|---|
--connectionRate |
-r |
NUM | - | 单连接每秒请求数 |
--overallRate |
-R |
NUM | - | 总每秒请求数 |
--ignoreCoordinatedOmission |
-C |
BOOL | false | 忽略协调遗漏 |
限速测试:
bash
# 限制总QPS为500
autocannon -R 500 http://localhost:3000
5. 高级功能参数
参数 | 缩写 | 类型 | 默认值 | 说明 |
---|---|---|---|---|
--bailout |
-B |
NUM | - | 失败次数阈值 |
--expectBody |
-E |
STRING | - | 预期响应体 |
--idReplacement |
-I |
BOOL | false | 启用ID替换 |
--debug |
- | BOOL | false | 调试模式 |
--renderStatusCodes |
- | BOOL | false | 状态码统计 |
6. 输出控制参数
参数 | 缩写 | 类型 | 默认值 | 说明 |
---|---|---|---|---|
--json |
-j |
BOOL | false | JSON格式输出 |
--latency |
-l |
BOOL | false | 显示完整延迟数据 |
--no-progress |
-n |
BOOL | false | 隐藏进度条 |
--title |
-T |
STRING | - | 测试标题 |
--excludeErrorStats |
-x |
BOOL | false | 排除错误统计 |
深入理解 --pipelining
参数
什么是 HTTP Pipelining?
HTTP pipelining 允许客户端在收到前一个响应之前就发送多个请求,大幅提升效率。
最适合的情况
- 高延迟网络:减少网络往返时间的影响
- HTTP/1.1 服务:HTTP/1.1 原生支持 pipelining
- 持久连接测试:测试服务端的长连接处理能力
不适用的情况
- HTTP/2 服务:HTTP/2 有更先进的 multiplexing 机制
- 非幂等操作:POST/PUT 等可能引发副作用的方法
- 严格顺序依赖:要求请求必须按顺序处理的场景
举个栗子:快递站取快递
假设你要取10个快递:
情况1:不加
-p
参数(默认-p 1
)
- 你每次只告诉快递站"我要拿1个快递"
- 拿到第1个后,再说"我要拿第2个"...
- 重复10次对话
- 问题:每次都要重新排队,效率低
情况2:加上
-p 10
参数
- 你直接告诉快递站:"我要一次性拿10个快递!"
- 快递站一次性准备好10个快递给你
- 优势:只排1次队,效率超高
工作原理对比
不加 pipelining (-p 1
) :
css
[请求1] -> [响应1] <-
[请求2] -> [响应2] <-
...
启用 pipelining (-p 10
) :
css
[请求1]->[请求2]->[请求3]... -> 服务器
[响应1]->[响应2]->[响应3]... <- 服务器
实际效果示例
bash
# 不启用 pipelining
autocannon -c 100 -d 10 http://localhost:3000
→ 约 5000 请求/秒
# 启用 pipelining
autocannon -c 100 -p 10 -d 10 http://localhost:3000
→ 约 15000 请求/秒(提升 3 倍)
最佳实践
- 从
-p 2-5
开始逐步增加 - 不要超过
-p 10
(除非服务端明确支持) - HTTP/2 服务不需要使用此参数
解读测试结果
典型输出示例:
bash
Running 10s test @ http://localhost:3000
10 connections
┌─────────┬──────┬──────┬───────┬──────┬─────────┬─────────┬───────┐
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
├─────────┼──────┼──────┼───────┼──────┼─────────┼─────────┼───────┤
│ Latency │ 8 ms │ 12 ms│ 25 ms │ 30 ms│ 13.4 ms │ 7.25 ms │ 50 ms │
└─────────┴──────┴──────┴───────┴──────┴─────────┴─────────┴───────┘
┌───────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
├───────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│ Req/Sec │ 715 │ 715 │ 892 │ 905 │ 853.6 │ 62.4 │ 715 │
└───────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘
Req/Bytes counts sampled once per second.
8k requests in 10.01s, 1.05 MB read
关键指标:
- Latency (延迟) :重点关注 99% 百分位的延迟
- Req/Sec (每秒请求数) :系统的吞吐量指标
- 错误率:检查是否有失败的请求
实战场景与参数组合
场景1:API基准测试
bash
autocannon -c 50 -p 3 -d 60 \
-m GET \
-H "Authorization: Bearer xyz" \
http://localhost:3000/api/users
场景2:登录压力测试
json
autocannon -c 100 -d 30 \
-m POST \
-H "Content-Type: application/json" \
-b '{"username":"user","password":"pwd"}' \
http://localhost:3000/login
场景3:文件上传测试
json
autocannon -c 20 -d 20 \
-m POST \
-F '{"file":{"type":"file","path":"/path/to/file.jpg"}}' \
http://localhost:3000/upload
进阶技巧
编程式调用
javascript
const autocannon = require('autocannon')
const instance = autocannon({
url: 'http://localhost:3000',
connections: 100,
duration: 30,
pipelining: 3,
headers: {
'X-Custom': 'value'
}
}, (err, result) => {
console.log('测试完成', result)
})
// 手动停止测试
setTimeout(() => instance.stop(), 5000)
CI/CD集成
arduino
# package.json
{
"scripts": {
"test:perf": "autocannon -c 50 -d 20 -j http://localhost:3000 > perf.json"
}
}
使用配置文件
创建 autocannon.json
:
json
{
"url": "http://localhost:3000",
"connections": 50,
"duration": 15,
"method": "GET",
"headers": {
"Authorization": "Bearer token123"
}
}
然后运行:
arduino
autocannon --config autocannon.json
与其他工具对比
工具 | 优势 | 适用场景 |
---|---|---|
autocannon(Javascript) | 轻量易用 | HTTP API测试 |
ab(C语言) | 简单 | 快速测试 |
wrk(C语言) | 高性能 | 极限压测 |
k6(Javascript) | 丰富场景 | 复杂负载测试 |
JMeter(Java) | 全面功能 | 企业级测试 |