php高并发压力测试需分场景选工具、看指标盯瓶颈、边压边调,否则无效甚至压崩环境;ab适合单接口吞吐极限测试但需注意-c与-k参数;jmeter适合真实链路测试须配置ramp-up和cookie管理;wrk因异步io更贴近现代php服务;php代码需内置耗时与内存监控;压测须多轮重复并重置环境。

PHP高并发压力测试不是“跑个ab命令就完事”,而是要分场景选工具、看指标盯瓶颈、边压边调——否则测了也白测,甚至把测试环境压崩。
ab命令怎么用才不踩坑
ab是入门首选,但参数稍错就失去参考价值。它本质是单机发请求,不适合模拟真实用户行为,只适合测单接口吞吐极限。
-
-c并发数 ≠ 真实用户数:100个-c可能瞬间打满后端连接池,但真实用户是逐步进入+带思考时间的 - 必须加
-k(Keep-Alive):否则每次请求都重建TCP连接,测的是网络握手性能,不是PHP处理能力 - 别信
200 OK:返回200不代表业务成功,比如下单接口返回200但库存扣超了,得加日志或响应断言验证 - 示例安全写法:
ab -n 5000 -c 200 -k -H "User-Agent: stress-test" http://localhost/api/order
JMeter怎么配才像真实流量
JMeter能模拟登录态、参数化、失败重试和思考时间,是测完整业务链路的主力工具,但配置不当容易变成“假并发”。
- 线程组里一定要设
Ramp-up period(比如10秒内拉起200用户),否则所有请求同时砸过来,纯粹测服务器抗冲击能力,不是测稳定性 - HTTP Cookie Manager 必须开启:否则登录态无法保持,后续接口全401/403,测的不是业务而是鉴权漏洞
- 用
JSON Extractor提取上一个响应里的token或订单号,传给下一个请求——这是测支付、下单等链路的刚需 - 别只看“平均响应时间”:重点盯
90% Line和95% Line,它们暴露尾部延迟问题,比如80%请求200ms完成,但最后5%卡在2s以上,说明有慢SQL或锁竞争
为什么wrk比ab更适合压API服务
ab是单线程+阻塞IO,而wrk用多线程+异步IO,压测时CPU占用低、连接复用强,更贴近现代PHP-FPM或Swoole服务的真实负载特征。
立即学习“PHP免费学习笔记(深入)”;
-
-t(线程数)建议设为CPU核心数,-c(连接数)可远高于-t,比如-t 4 -c 400,模拟4个线程维持共400个长连接 - 加
-s script.lua可注入动态参数:比如每次请求带不同user_id或随机timestamp,避免被缓存命中干扰结果 - 注意wrk默认不校验SSL证书,压HTTPS时若遇到证书错误,加
--insecure;但生产环境务必关掉这个开关 - 示例:
wrk -t4 -c400 -d30s --latency -s auth.lua https://api.example.com/v1/profile
压测时PHP代码里必须加什么
光靠外部工具不够,PHP脚本内部得有“自证清白”的能力,否则你根本不知道是网络慢、DB慢,还是某段foreach写死了。
- 每个关键路径开头记时间戳,结尾用
microtime(true)算耗时,写进error_log()或Monolog,别用echo——压测时输出会拖慢本身 - 数据库操作前后加
debug_backtrace()简略版(只取前2层),定位慢查询来自哪个控制器方法 - 在
register_shutdown_function()里检查是否超时或内存溢出,记录memory_get_peak_usage(),防止“没报错但悄悄OOM” - 示例日志片段:
error_log("[API] /v1/order create | UID:1024 | DB:128ms | Total:312ms | Mem:8.2MB");
最常被忽略的一点:压测不是一次性动作。一次ab -c 500跑完看到QPS翻倍,不代表系统变强了——可能只是OPcache刚热身完。真正可靠的结论,得在相同环境、相同数据量、相同监控维度下,至少跑3轮,且每轮中间清空Redis、重启PHP-FPM、重置MySQL查询缓存。











