frankenphp有经典模式和worker模式两种运行方式,默认启动为经典模式(每次请求完整初始化php),仅显式启用worker模式(如frankenphp run --worker)才实现php常驻内存,压测前须用ps或health接口确认模式,否则qps对比无效。

ab压测前必须确认的FrankenPHP运行模式
FrankenPHP有「经典模式」和「Worker模式」两种启动方式,ab测出来的QPS差异可能翻倍,但很多人压测时根本没意识到自己跑的是哪一种。默认不加任何参数启动frankenphp,它走的是经典模式——本质就是个带Caddy的PHP-FPM替代品,框架每次请求仍会完整初始化;只有显式启用Worker模式(如通过frankenphp run --worker或Docker环境变量FRANKENPHP_WORKER=1),PHP才真正常驻内存。压测前务必用ps aux | grep php或curl -s http://localhost/health | jq确认进程模型,否则对比毫无意义。
用ab做公平对比的三个硬性条件
想让Nginx+PHP-FPM和FrankenPHP的ab结果可比,必须抹平环境干扰项:
- 两个服务都绑定到
127.0.0.1:8000这类本地端口,避免DNS解析、网络延迟引入误差 - 被测脚本必须完全一致:比如都用
public/index.php(Laravel)或一个裸test.php输出phpversion(),不能一个测路由一个测静态文件 - 压测命令参数严格统一:
ab -n 2000 -c 200 -k(-k开启HTTP Keep-Alive,否则TCP建连开销会淹没PHP本身性能)
特别注意:FrankenPHP内置Caddy默认启用HTTP/2,而ab不支持HTTP/2,它实际走的是HTTP/1.1降级通道——这反而让对比更“保守”,结果可信度更高。
ab输出里真正要看的三行指标
ab返回一堆数字,但只盯这三项才能看出迁移价值:
-
Requests per second:直接反映吞吐量,FrankenPHP Worker模式下通常比FPM高2–4倍(Laravel典型场景从300→1200 QPS) -
Time per request (mean):平均延迟,重点看「后90%请求」的毛刺——FPM常见几十ms尖峰,FrankenPHP Worker因无重复bootstrap会更平滑 -
Failed requests:如果FrankenPHP出现非零失败,大概率是扩展缺失(如漏装pcntl)或opcache未启用,而不是服务崩溃
别信Percentage of the requests served within a certain time里的百分位数,ab单线程发压,统计口径和真实并发不一致。
FrankenPHP特有的压测陷阱
你可能把ab跑通了,但结果依然不准,因为FrankenPHP有几个隐藏开关会影响基准:
- 没开
opcache.enable=1且opcache.enable_cli=1:FrankenPHP的CLI子进程也走opcache,不开等于放弃一半性能 - Docker部署时没映射
/tmp:FrankenPHP内部用/tmp/frankenphp存共享内存,容器里/tmp被清空会导致Worker反复重启 - 误用
frankenphp php-cli -v测PHP版本,却忘了frankenphp run实际加载的是php.ini里另一套配置,opcache、memory_limit等必须在FrankenPHP自己的ini路径下改(通常是/etc/php/conf.d/或镜像内/usr/local/etc/php/conf.d/)
最隐蔽的坑是:ab压测时FrankenPHP日志里出现max_requests limit reached,说明Worker被强制回收了——这时要调大MAX_REQUESTS环境变量,否则压测中途性能断崖下跌。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











