你上线了一个接口。它在 Postman 中能返回正确的 JSON。但你完全不知道当 200 个客户端同时访问它时会发生什么。它能承受每秒 500 次请求,还是在并发量达到 50 时延迟就崩溃了?ApacheBench 仅需一条命令就能回答这个问题。
ApacheBench(命令为 ab)是一个命令行工具,它向单个 URL 发送固定数量的 HTTP 请求,并报告吞吐量和延迟。它随 Apache HTTP Server 一起提供,已经存在了数十年。它体积小巧、运行快速,能让你快速了解单个接口所能承受的负载。
本指南将介绍如何安装 ab、运行基础测试、测试 POST 接口、解读输出结果,以及了解在哪些场景下 ab 不再是首选工具。此处介绍的每个命令都对应官方 Apache ab reference 中记录的参数。
什么是 ApacheBench 以及它从何而来
ab 是随 Apache HTTP Server 捆绑的基准测试客户端,其名称是 ApacheBench 的缩写。它会与单个 URL 建立连接,在并发设置允许的范围内尽可能快地发送请求,记录每次响应的时间,并打印出分析摘要。

它能很好地测量一件事:单个接口每秒可以处理多少次请求,以及在负载下响应时间的分布情况。这就是单个 URL 的吞吐量和延迟。
它不能做的事情同样重要。ab 不会检查响应 body 是否正确,不会验证数据模型,也不会对字段进行断言。它不能执行诸如“登录、获取数据、然后更新”等多步骤流程。它只是持续请求单个 URL 并计数。记住这一局限性,ab 就会是一个很有用的工具。如果对它期望过高,你可能会感到失望。
如果你想更全面地了解 ab 所属的领域,请参阅什么是 API 负载测试以及为什么 API 响应时间至关重要。
安装 ab
ab 随 Apache 工具包一起分发,其包名在不同平台上有所不同。
在 Debian 和 Ubuntu 上,安装 apache2-utils 包:
sudo apt-get update
sudo apt-get install -y apache2-utils
在 CentOS、RHEL 和 Fedora 上,该软件包为 httpd-tools:
# CentOS 7
sudo yum install -y httpd-tools
# Fedora and CentOS 8+
sudo dnf install -y httpd-tools
在 macOS 上,由于系统自带 Apache,因此已经预装了 ab。你可以运行以下命令进行检查:
ab -V
你应该会看到类似 Version 2.3 的版本信息。如果 macOS 上缺少该命令,可以通过 Homebrew 的 Apache formula 进行安装。一旦 ab -V 成功打印出版本号,说明你已经准备就绪。
运行基础负载测试
每次使用时,最常用的两个参数是 -n 和 -c。
-n requests用于设置要执行的请求总数。默认值为 1 次请求,这无法反映真实情况,因此请务必设置此参数。-c concurrency用于设置同时运行的并发请求数。默认值为 1,表示完全串行执行。
以下是对一个返回 JSON 的接口执行 1000 次请求(每次并发 50 个请求)的示例:
ab -n 1000 -c 50 https://api.example.com/v1/users注意末尾的路径。ab 需要一个带有路径的完整 URL。如果将其指向一个没有路径的纯主机名,它会报错。对于根路径,请使用末尾斜杠:https://api.example.com/。
真实的客户端会复用 TCP 连接,而不是为每个请求都新建一个连接。添加 -k 参数可以启用 HTTP KeepAlive,从而让 ab 在同一个会话中复用连接:
ab -n 1000 -c 50 -k https://api.example.com/v1/users使用 -k 参数运行的测试通常更接近浏览器或表现良好的 API 客户端的行为,因为它避免了在每个请求上都付出建立连接的开销。对比这两个数值,可以观察出延迟中有多少是由连接开销造成的。
你也可以通过时间而不是请求次数来限制运行。-t 用于设置最大秒数,并且内部默认指定了 -n 50000,因此测试会在最先达到的限制处停止:
ab -t 30 -c 50 -k https://api.example.com/v1/users
bash cat > payload.json <<'EOF' {"name": "Ada Lovelace", "email": "ada@example.com"} EOF
然后发送它:
这将在并发数 50 下最多运行 30 秒。当你想要进行固定时长的读取测试而不是固定次数的测试时,这非常方便。
测试 POST 接口
大多数 API 的工作不仅仅是 GET。要测试 POST 接口,请将请求 body 放入一个文件中,并通过 -p 参数传递它。你还必须使用 -T 来设置 content type,否则服务端会拒绝该 body。
创建 payload:
ab -n 500 -c 25 -k \ -p payload.json \ -T application/json \ https://api.example.com/v1/users
-p 标志指定了包含 POST body 的文件。-T 标志设置 Content-Type header。默认的 content type 是 text/plain,这几乎不是 JSON API 所需要的,所以请显式设置 -T application/json。
如果你的接口需要 auth 或其他 header,可以使用 -H 添加它们。为每个 header 重复使用该标志:
ab -n 500 -c 25 -k \ -p payload.json \ -T application/json \ -H "Authorization: Bearer YOUR_TOKEN" \ https://api.example.com/v1/users要温习如何手动构建 JSON 请求 body,请参阅如何使用 curl 发送 POST JSON 数据。相同的 body 可以直接用作 ab 的 payload 文件。
读取输出结果
运行后会输出一整块数据。下面是一个裁剪后的示例:
Concurrency Level: 50 Time taken for tests: 4.212 seconds Complete requests: 1000 Failed requests: 0 Non-2xx responses: 0 Requests per second: 237.42 #/sec Time per request: 210.598 ms Time per request: 4.212 [ms] (mean, across all concurrent requests) Transfer rate: 142.31 [Kbytes/sec] received
Connection Times (ms) min mean[+/-sd] median max Connect: 5 18 9.4 16 64 Processing: 22 189 41.2 182 310 Waiting: 21 177 39.8 171 295 Total: 31 207 42.7 201 338
Percentage of the requests served within a certain time (ms) 50% 201 66% 221 75% 236 90% 268 95% 291 99% 324 100% 338 (longest request)
首先查看以下字段:
- Requests per second(每秒请求数)是吞吐量指标。它是请求总数除以总时间。数值越高越好。
- Failed requests(失败请求数)和 Non-2xx responses(非 2xx 响应数)可以告诉你服务端是否真正承受住了负载,还是已经开始报错。如果有一半的响应是 500,那么高每秒请求数就毫无意义。在信任吞吐量数据之前,请务必先检查这两项。
- Time per request(每个请求耗时)出现了两次。第一行是单个用户等待的平均时间(并发数乘以总时间再除以请求数)。第二行标注为“across all concurrent requests”,是完成请求之间的平均间隔。第一个数值才是用户能切身感受到的。
Percentage of the requests served within a certain time(在特定时间内处理的请求百分比)表格是最有用的部分。它是按百分位数进行拆分的。50% 行是你的中位数。95% 和 99% 行显示了长尾延迟。在示例中,有一半的请求在 201ms 内完成,但有 1% 的请求耗时 324ms 或更长。长尾延迟是真正伤害用户体验的地方,因此相比平均值,应更加关注第 95 和第 99 百分位数。
想要获取用于图表的原始单次请求数据吗?添加 -e results.csv 可以写入包含“百分位数-耗时”对的 CSV 文件,或者添加 -g results.tsv 来生成适合 gnuplot 的文件。
什么时候 ab 不再是合适的工具
ab 的功能定位故意设计得很单一。有必要清楚地说明它的局限性,以免你误用它。
每次运行只能测试一个 URL。ab 只能对单个接口进行压力测试。它无法编写串联流程的脚本,例如先身份验证,再创建资源,最后读取资源。真实的用户链路会按顺序触达多个接口,而 ab 完全没有这个概念。
没有正确性检查。ab 只计算状态码和字节长度。它不会解析你的 JSON,也不会断言某个字段是否等于预期值。一个响应可能在结构上已经是错误的,但仍被算作成功。负载数据并不能代替通过的测试套件。
过时的 HTTP 处理。官方文档指出 ab 并没有完全实现 HTTP/1.x,并且只接受某些特定格式的响应。它不支持 HTTP/2。对于在 HTTP/2 下表现不同的服务端,ab 无法反映出这种差异。
单机负载。ab 在单台机器和单个进程上运行。超过一定的并发量后,你测试的其实是自己客户端的极限,而不是服务端的极限。文档甚至警告说,ab 自身的解析开销可能会在性能分析中成为瓶颈。
这些局限性并不意味着 ab 不好。它只是一个特定用途的工具:针对单个接口的快速吞吐量探测器。当你需要脚本化流程、分布式负载或 HTTP/2 支持时,请选择专门为此设计的工具。JMeter 可以处理多步骤场景和分布式运行,如果你在对比不同的选择,还有更多更广泛的负载测试工具可供参考。
功能测试的适用场景
吞吐量是一个维度,而正确性是另一个维度,ab 并不涉及后者。在对接口进行负载测试之前,你需要确保它在正常情况下能返回正确且符合预期格式的数据。这就是功能测试和契约测试,属于不同的工作范畴。
这就是为什么在 ab 之外,还需要一个完整的 API 平台。Apifox 允许你通过可视化断言构建测试场景,将请求串联为多步骤工作流,并根据你的数据模型校验响应,这些都是 ab 在设计上无法实现的。你只需保存一次这些测试场景,即可在任何地方运行它们。
对于持续集成,Apifox CLI 可以以无头(headless)模式运行你保存的测试场景。使用 Node 安装它:
npm install -g apifox-cli
然后针对选定的环境运行保存的测试场景或套件,并生成可供 CI 归档的报告:
apifox run \ --access-token "$APIFOXACCESSTOKEN" \ -t\ -e\ -r cli,html,junit-t 参数通过 ID 指定保存的测试场景、目录或套件。-e 参数选择环境。-r 参数从 cli、html、json 和 junit 中选择一个或多个报告生成器。对于数据驱动的运行,可以添加 -d(或 --iteration-data)并指定数据文件路径或测试数据 ID。该 CLI 是无头的,专门运行已保存的测试场景,因此它适用于任何能够运行 Node 的 CI 步骤。它不是请求发送器,也不是负载生成器,它运行的是 ab 根本无法执行的功能测试。
一个健康的体系应该同时使用这两者。运行 Apifox 测试场景来证明接口的正确性;运行 ab 来证明它的速度足够快。关于正确性方面,请参阅 Apifox 性能测试指南和通用的 API 性能测试教程。
FAQ
ApacheBench 只能用于 Apache 服务器吗?
不是。尽管名为 ApacheBench,ab 可以向任何服务端发送普通的 HTTP 和 HTTPS 请求。它适用于 Nginx、Node、Go、Python 或任何支持 HTTP 协议的主机。与 Apache 的唯一关联是该工具随 Apache HTTP 服务器一同发布。
我应该使用多少并发量和请求数?
从低并发开始逐步提升。尝试运行 -n 1000 -c 10,然后将 -c 提高到 25、50、100,并观察每秒请求数何时停止增长以及何时开始出现失败的请求。那个拐点大致就是接口达到饱和的地方。请根据预期的实际流量来设定峰值并发量,而不是盲目选择一个较大的整数。
为什么当 API 运行正常时,我的失败请求数却很高?
如果不同请求之间的响应长度有所不同(这对于动态 JSON 来说很正常),ab 会将该请求标记为失败。添加 -l 参数可以停止将长度差异计为失败。然后再检查 Non-2xx responses 行,看看底层是否存在真正的错误。
ab 可以测试需要登录 Token 的接口吗?
可以,前提是你已经拥有了 Token。你可以通过 -H "Authorization: Bearer YOUR_TOKEN" 传入它。但 ab 无法做到的是先登录以获取新的 Token,然后再使用它。这是一个多步骤的工作流,为此你需要像 Apifox 这样基于场景的工具。
ab 支持 HTTP/2 吗?
不支持。ab 采用的是 HTTP/1.x,并且根据官方文档,它甚至没有完整实现该协议。如果你的服务端在 HTTP/2 下的表现很重要,请改用支持 HTTP/2 的压测工具。
开发必备:API 全流程管理神器 Apifox
介绍完上文的内容,我想额外介绍一个对开发者同样重要的效率工具 —— Apifox。作为一个集 API 文档、调试、设计、测试、Mock、自动化测试于一体的工具,Apifox 是目前提升研发效率的首选。
如果你正在开发项目,不妨试试其极其友好的界面设计,它完全兼容 Postman 和 Swagger 数据格式,导入数据非常方便,,即使是新手也能很快上手,点击这里即可注册使用。

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