hyperf 与 php-fpm 互斥,不兼容也不依赖 fpm;它基于 swoole 常驻内存运行,直接监听端口,绕过 fastcgi 和 nginx→fpm 链路,启动后 fpm 完全无关。

不能。Hyperf 和 PHP-FPM 是互斥的运行模型,Hyperf 服务本身不依赖、也不兼容 FPM 进程生命周期,所谓“用 Hyperf 规避 FPM 进程创建损耗”是个根本性误解。
Hyperf 启动后就不再经过 FPM
Hyperf 是基于 Swoole 的常驻内存协程框架,启动时直接监听端口(如 0.0.0.0:9501),由 Swoole Worker 进程接管全部请求。它完全绕过 FastCGI 协议和 Nginx → FPM 这条链路。一旦你用 php bin/hyperf.php start 启动 Hyperf,FPM 进程就彻底无关——既不会被调用,也不会被复用。
- FPM 的
pm.max_children、pm.status_path等配置对 Hyperf 无效 - Nginx 的
fastcgi_pass指向 FPM socket 的配置,在 Hyperf 场景下应改为proxy_pass http://127.0.0.1:9501 - 试图在 Hyperf 项目里同时启用 FPM(比如误配 Nginx)会导致 502 或请求静默丢失
真正要规避的不是“FPM 进程创建”,而是“状态残留”
PHP-FPM 的痛点是进程级隔离:每次请求结束,整个进程内存清空,所有类实例、PDO 连接、静态变量全销毁。而 Hyperf 的风险正好相反——进程长期存活,但若代码写法不当,会导致状态污染:
-
static $cache = []在协程间共享,不同用户请求互相覆盖 - 把
$this->userId存在 Service 实例属性里,后续请求读到上一个用户的 ID - 用
file_get_contents()阻塞 Worker,导致并发能力断崖下跌
这些不是“损耗”,是数据错乱或性能崩塌的前兆。Hyperf 不提供自动清理,必须靠编码规范兜底。
Hyperf 里连接复用靠的是协程池,不是持久化连接
FPM 下的 PDO::ATTR_PERSISTENT = true 是进程绑定、跨请求复用 TCP 连接;Hyperf 的 Hyperf\DbConnection\Db 默认启用连接池,原理完全不同:
- 连接池大小由
pool.min_connections和pool.max_connections控制,不是按需新建,而是预分配 + 复用 - 连接归还池时会执行
PING检测,失效连接自动剔除,不依赖ATTR_PERSISTENT - MySQL 连接池与 Redis 连接池相互独立,各自管理,避免混用导致超时或协议错乱
如果你在 Hyperf 里手动 new PDO 并设 ATTR_PERSISTENT,反而会因连接未归还池、TCP 端口耗尽而报 Connection refused。
迁移时最容易忽略的点:Nginx 配置和健康检查路径
从 FPM 切到 Hyperf,最常卡住的不是代码,而是反向代理层:
- Nginx 的
location ~ \.php$规则必须删除或注释,否则所有 .php 请求仍打给 FPM - 健康检查接口(如
/health)不能依赖 FPM 的pm.status_path,得自己实现返回200+memory_usage等指标 - 如果用了 HTTPS,Swoole 默认不处理 SSL,必须让 Nginx 终止 TLS,再以 HTTP 转发给 Hyperf
Hyperf 启动后,ps aux | grep swoole 应看到 php bin/hyperf.php start 进程,而不是一堆 php-fpm。看到后者,说明你还在走 FPM 链路,没切成功。











