frankenphp每个worker进程同一时刻只处理一个php请求,采用同步阻塞模型,并发依赖worker数量而非单进程多路复用。

不会。FrankenPHP 的每个 Worker 进程同一时刻只处理一个 PHP 请求。
FrankenPHP 的 Worker 是同步阻塞模型
FrankenPHP 基于 Go 编写的 SAPI,其 Worker 进程(由 frankenphp.Worker 启动)在接收到一个 HTTP 请求后,会完整执行整个 PHP 生命周期:初始化、解析脚本、运行逻辑、输出响应、释放资源。这个过程是同步且阻塞的——期间无法接收或处理第二个请求。
这和传统 PHP-FPM 的 pm = static 或 pm = dynamic 下的 Worker 行为一致,区别只在于底层调度器换成了 Go 的 goroutine + HTTP server,而非 Unix fork + FastCGI。
- 每个 Worker 对应一个独立的 PHP 执行上下文(
php_request_startup()→php_request_shutdown()) - 没有协程自动挂起/恢复机制;不使用
Swoole\Coroutine或OpenSwoole那类用户态调度 - 即使你用
async/await(需 ext-parallel 或自定义封装),也不会改变 Worker 单请求串行的本质
并发靠的是 Worker 数量,不是单个 Worker 并发能力
FrankenPHP 的并发吞吐取决于你配置的 Worker 池大小(frankenphp.workers),而不是单个 Worker 能否“多路复用”请求。
例如:
frankenphp: workers: 8
意味着最多有 8 个请求被并行执行,第 9 个请求会排队等待空闲 Worker。
- Worker 数设太少(如
workers: 2),高并发下大量请求堆积在 Go 层的 HTTP 连接队列中,表现为延迟升高、超时增多 - Worker 数设太多(如 > CPU 核心数 × 2),反而因上下文切换和内存占用导致整体性能下降
- PHP 内存限制(
memory_limit)对每个 Worker 独立生效,OOM 容易 kill 掉单个 Worker,但不影响其他 Worker
别和 Swoole/Workerman 的“单进程万连接”混淆
FrankenPHP 不是事件驱动框架,它不提供 Swoole\Http\Server 那样的单进程异步 I/O 能力,也没有 Workerman\Worker 的内置 event loop。
如果你看到“FrankenPHP 支持协程”,那是指它能运行基于 ext-parallel 或 amphp 的异步 PHP 代码,但这些异步操作仍运行在某个单一 Worker 的线程内,并不改变该 Worker 此刻只能服务一个请求的事实。
-
frankenphp.Worker是进程级隔离单位,不是协程调度器 - 它不接管 PHP 的
stream_select()或curl_multi底层行为;那些仍是 PHP 自己的阻塞/非阻塞逻辑 - 真正想让单个 PHP 实例处理多个并发 I/O,得靠业务层用
amphp/http-server或spiral/roadrunner这类嵌套方案,FrankenPHP 本身不参与
最容易被忽略的一点:FrankenPHP 的 Worker 生命周期比 PHP-FPM 更长(常驻),但它对每个请求的“独占性”反而更彻底——因为没有 FastCGI 的 request 复用 socket 机制,每个请求都触发一次完整的 PHP 初始化流程。这意味着,哪怕你只是 echo "hello",也要走一遍 Zend 引擎加载、OPcache 查找、全局变量重置……别指望靠“轻量请求”来摊薄开销。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











