ab 命令可快速进行真实 HTTP 压测,避免 PHP 脚本误判瓶颈;一行命令 ab -n 1000 -c 100 http://localhost:8000/api/users 即得 QPS、延迟与失败率。

用 ab 快速跑一次真实 HTTP 压测,别写 PHP 脚本
PHP 本身不是压测工具,硬用 curl_multi_exec 模拟并发,容易误判瓶颈——你测的其实是 PHP 的 I/O 调度和内存管理,不是目标服务的真实吞吐。真正要测接口扛不扛得住,直接用专业压测命令更准、更快、更轻量。
Linux/macOS 自带的 ab(Apache Bench)就能干这事,一行命令起压,结果含 QPS、延迟分布、失败率:
ab -n 1000 -c 100 http://localhost:8000/api/users
注意点:
-
-n 1000是总请求数,-c 100是并发连接数,别一上来就-c 5000,先从 50/100 起步观察服务反应 -
ab不支持 POST JSON 或带 Header 的复杂请求?加-p post_data.json -T "application/json" - Windows 下没
ab?装choco install apachebench或直接用wrk(更现代,支持脚本化) - PHP-FPM 进程数、MySQL 连接池、Redis 连接数这些后端资源,在压测前必须确认是否已调优,否则
ab报的“失败”大概率是服务端拒绝,不是代码问题
真要用 PHP 写并发请求脚本?绕开 curl_multi_exec 的坑
很多人抄网上的 curl_multi_exec 示例,结果发现并发数上不去、超时乱飞、内存暴涨——根本原因是它默认不设超时、不回收句柄、不处理 DNS 缓存,且对 HTTPS 重试逻辑极不友好。
立即学习“PHP免费学习笔记(深入)”;
如果非得用 PHP 发并发请求(比如要动态构造参数、做登录态维持、或集成进 CI 流程),推荐用 GuzzleHttp\Client 配合 Promise:
$client = new GuzzleHttp\Client(['timeout' => 5]);
$promises = [];
for ($i = 0; $i < 50; $i++) {
$promises[] = $client->getAsync('http://api.example.com/test', [
'headers' => ['X-Trace-ID' => uniqid()],
]);
}
$results = Promise\settle($promises)->wait();
关键控制点:
- 务必设
timeout,否则一个卡死请求会拖垮整批 Promise - 别用
curl_multi_exec手动轮询,Guzzle 的settle()自动处理完成/失败/异常三种状态 - 并发数别硬写 500,PHP CLI 默认内存限制 128M,每请求占几 MB,50 并发就可能 OOM
- 不要在循环里反复 new Client,复用同一个实例,避免 TCP 连接爆炸
压测时看到 502 Bad Gateway 或 Connection refused?先查 Nginx 和 PHP-FPM
这类错误基本和你的 PHP 代码无关,而是网关层或 PHP 运行时撑不住了。常见链路是:Nginx → PHP-FPM → MySQL/Redis。
快速定位方向:
-
systemctl status php-fpm看是否进程崩溃或被 OOM killer 杀过 - 检查
/var/log/php-fpm/www-error.log里有没有WARNING: [pool www] server reached pm.max_children - Nginx 的
error.log出现upstream prematurely closed connection?说明 PHP-FPM 没响应完就断了,调大request_terminate_timeout和pm.max_requests - 用
ss -ant | grep :9000 | wc -l看 FPM 连接数是否打满(默认 32)
别拿本地开发环境当压测靶机
Mac 上用 MAMP、Windows 用 XAMPP、甚至 Docker Desktop,默认配置全是玩具级:PHP 单进程、MySQL 无连接池、Nginx worker_processes=1。你在本地压出 20 QPS,上线后可能连 200 都不到。
真实压测环境至少要满足:
- 用和生产一致的 PHP 版本 + OPcache 开启(
opcache.enable=1) - 数据库用独立服务器或至少 Docker Compose 分离,禁用
query_cache(MySQL 8+ 已移除) - 关闭 Xdebug、Blackfire、Laravel Telescope 这类调试扩展,它们会让性能下降 3–10 倍
- 压测机和被测服务别跑在同一台机器上,网络栈和 CPU 争抢会污染结果
压测不是比谁脚本写得炫,是比谁漏掉的配置更少。一个没调的 pm.max_children,比十个并发脚本都致命。



















