要让Nginx与PHP-FPM真正复用TCP连接,必须协同配置upstream长连接池、FastCGI协议层握手控制和PHP-FPM并发容量对齐;phpEnv默认关闭该机制,需手动补全并验证。

要让 Nginx 与 PHP-FPM 之间真正复用 TCP 连接,不能只靠 keepalive_timeout 或简单改个端口,必须在三个层面协同配置:upstream 长连接池、FastCGI 协议层握手控制、PHP-FPM 自身并发容量对齐。phpEnv 默认完全关闭该机制,需手动补全并验证。
一、定义 upstream 并启用 keepalive 连接池
phpEnv 的 nginx.conf 默认没有 upstream 块,所有 PHP 请求直连 fastcgi_pass 127.0.0.1:9000,这种写法天然不支持长连接。你得在 http 块顶部手动添加:
- 复制以下内容到
nginx.conf的http { ... }内最上方(不要放在 server 或 location 里):
upstream php_backend {
server 127.0.0.1:9000;
keepalive 12;
keepalive_requests 1000;
keepalive_timeout 60s;
}
-
keepalive 12表示每个 Nginx worker 最多维持 12 个空闲连接;设太高会超 PHP-FPM 总并发上限(如默认pm.max_children = 10,则 12 已偏高,建议 8–12) -
keepalive_requests 1000防止单连接过早断开;值应与 PHP-FPM 的pm.max_requests接近(如后者为 1000,这里也设 1000) -
keepalive_timeout 60s是空闲连接保持时间,不是全局keepalive_timeout,两者无关
二、location 中强制 HTTP/1.1 + 清空 Connection 头
仅 upstream 开启 keepalive 不够——若协议版本不对或头信息干扰,Nginx 仍会降级为短连接。在 location ~ \.php$ 块中,替换原 fastcgi_pass 并补充两行:
- 把原来的
fastcgi_pass 127.0.0.1:9000;改成:
fastcgi_pass php_backend; fastcgi_http_version 1.1; fastcgi_set_header Connection "";
-
fastcgi_http_version 1.1是关键:它让 Nginx 使用 FastCGI over HTTP/1.1 语义通信,这是复用连接的协议基础 -
fastcgi_set_header Connection ""必须是空字符串(双引号内无空格),不是"keep-alive"也不是"close";否则 PHP-FPM 会误判并主动断连 - 确保
include fastcgi_params;仍在,避免丢失SCRIPT_FILENAME等必要参数
三、同步调高 PHP-FPM 的并发处理能力
upstream 维持 12 个空闲连接,但 PHP-FPM 实际只能同时处理 10 个请求(默认 pm.max_children = 10),多余连接就会被拒绝,出现偶发 502。需修改 PHP-FPM 配置:
立即学习“PHP免费学习笔记(深入)”;
- 打开
php.ini同级目录下的php-fpm.d/www.conf(或 phpEnv 对应的 pool 配置文件) - 调整以下三项(以 Windows 下稳定运行为前提):
pm = dynamic pm.max_children = 16 pm.start_servers = 4 pm.min_spare_servers = 4 pm.max_spare_servers = 8 pm.max_requests = 1000
-
pm.max_children = 16至少 ≥ upstream 的keepalive值(如设了 12,这里至少 12,建议 16 更稳妥) -
pm.max_requests = 1000应与 upstream 的keepalive_requests一致,避免连接复用次数不匹配 - 保存后重启 php-fpm 和 nginx 服务
四、验证是否生效
别只看配置有没有报错,要实测连接状态:
- 执行命令:
netstat -an | findstr :9000(Windows)或ss -tnp | grep :9000(Linux) - 正常情况:大量
ESTABLISHED连接长期存在,而非瞬间新建又变TIME_WAIT - 压测时观察 QPS 提升和 502 错误是否消失;若仍有 502,优先检查
pm.max_children是否不足 - 浏览器 Network 面板看到 client→Nginx 是 keep-alive,不代表 Nginx→PHP-FPM 也是——后段必须单独验证



















