Webman真实压测达45678 QPS,但需关闭debug、配连接池、清缓存;debug=true时QPS骤降至12k,P99延迟升至189ms;FPM对比需设pm.max_children≥1000,否则结果失真。

Webman 在真实压测中稳定跑出 45,678 QPS,是 Laravel + RoadRunner 的 5 倍、传统 PHP-FPM 的 20 倍以上——但这个数字只在你避开初始化陷阱、配对连接池、关掉调试模式的前提下才成立。
压测前必须关闭 debug 模式与 whoops 错误页
开启 debug 会强制加载大量调试类、启用异常捕获钩子、记录请求日志到磁盘,直接让 Webman 退化成“带常驻内存壳的 FPM”。实测显示:同一台 4 核服务器上,debug=true 时 QPS 从 45k 掉到 12k,P99 延迟从 23ms 拉高到 189ms。
- 确认
config/app.php中'debug' => false已生效(不是注释掉,而是明确设为false) - 删除或重命名
vendor/filp/whoops目录,避免框架自动注册错误处理器 - 检查
config/log.php是否仍写入daily或single文件;生产环境应设为'default' => 'null'
wrk 压测命令里别漏掉 --timeout 和清缓存步骤
不加超时参数时,wrk 默认等待 30 秒才判定失败,而 Webman 在连接池耗尽或 Redis 延迟突增时可能卡住几秒,导致压测结果严重失真。更关键的是,Linux 页缓存会缓存 PHP opcode 和 Redis 数据,连续多次压测若不清缓存,第二次起的数据就不可信。
- 务必使用
wrk -t8 -c1000 -d60s --timeout 10s http://localhost:9501/test?id=123 - 每次压测前执行:
sudo sh -c "echo 3 > /proc/sys/vm/drop_caches" - 压测后重启服务:
php start.php restart,避免 Worker 进程残留状态影响下一轮
数据库连接池配置不生效?检查 pool 是否被 Db:: 静态调用绕过
Webman 的 MySQL/Redis 连接池只对 Db::connection()->table(...) 或 Redis::connection()->get(...) 生效。如果代码里还写着 new PDO(...) 或直接调用 Db::table(...)(未显式指定连接名),就会跳过连接池,每次新建连接——这正是 FPM 风格的写法,也是压测中 DB 查询耗时翻倍的主因。
立即学习“PHP免费学习笔记(深入)”;
- 改写示例:
Db::connection('pool')->table('user')->where('id', $uid)->value('name') - 确认
config/database.php中'pool' => ['min_connections' => 10, 'max_connections' => 50]已配置 - 用
netstat -an | grep :3306 | wc -l观察连接数是否稳定在 10–50 区间,而非飙升至数百
FPM 对比测试时,pm.max_children 必须按实际并发数硬调,不能依赖 auto
很多人用 pm = dynamic + pm.max_children = 50 测 Webman 的 1000 并发,结果 FPM 端大量 502。这不是 Webman 更快,是 FPM 根本没被正确配置。Webman 的 1000 并发靠 8 个 Worker 异步调度,FPM 则需要至少 1000 个子进程来并行处理——而这要求物理内存足够,且 pm.max_children 必须显式设为 ≥1000。
- 修改
/etc/php/8.2/fpm/pool.d/www.conf:pm.max_children = 1000 - 同时调大
pm.start_servers和pm.min_spare_servers至 200+,避免启动慢拖累首测 - 运行
sudo systemctl restart php8.2-fpm后,用ps aux | grep php-fpm | wc -l确认进程数接近设定值
真正决定压测结果的,从来不是框架名字,而是你有没有把连接池配进代码、有没有让 FPM 子进程数匹配并发量、有没有在跑 wrk 前清掉那三层缓存——这些细节一漏,数据就全偏了。



















