phpenv长连接需手动配置:在nginx.conf中定义upstream并启用keepalive,替换fastcgi_pass直连;同步调高php-fpm的pm.max_children至≥16,并设置fastcgi_http_version 1.1和connection空头,最后通过netstat验证established连接持续存在。

phpEnv 是一个 Windows 下集成 Nginx + PHP + MySQL 的轻量级环境套件,底层用的是标准 Nginx 二进制,但默认配置完全关闭了 upstream 长连接——这意味着每次请求都会新建后端连接,PHP-FPM 压力陡增,QPS 稍高就容易触发 502 Bad Gateway 或响应延迟飙升。
upstream keepalive 必须显式启用
phpEnv 的 nginx.conf 默认不带 upstream 块,所有 PHP 请求都走 fastcgi_pass 直连,而 fastcgi_pass 不支持 keepalive 指令。要启用长连接,必须把 PHP-FPM 抽成独立 upstream:
- 在
http块顶部添加:upstream php_backend { server 127.0.0.1:9000; keepalive 16; } - 在
location ~ \.php$块中,把原来的fastcgi_pass 127.0.0.1:9000;替换为:fastcgi_pass php_backend; fastcgi_http_version 1.1; fastcgi_set_header Connection "";
-
keepalive 16是安全起点:Windows 下单个 worker 进程线程资源有限,设太高反而触发connect() failed (10048: Only one usage of each socket address is permitted)
fastcgi_http_version 和 Connection 头不能省
即使加了 keepalive,如果没配协议版本和头清理,Nginx 仍会以 HTTP/1.0 方式发请求,后端(PHP-FPM)收不到复用信号,连接立刻断开:
-
fastcgi_http_version 1.1强制使用 FastCGI over HTTP/1.1 语义(注意不是proxy_http_version,那是给 HTTP 后端用的) -
fastcgi_set_header Connection ""清空客户端传来的Connection头,避免 PHP-FPM 被误导;设成"keep-alive"反而会出错 - 漏掉任一者,
netstat -an | findstr :9000会显示大量TIME_WAIT,而非稳定维持的ESTABLISHED连接
PHP-FPM 自身连接池要对齐
phpEnv 自带的 PHP-FPM 默认是 pm = dynamic,但 pm.max_children = 10 太小,而 upstream 的 keepalive 16 会尝试维持最多 16 个空闲连接——若 PHP-FPM 实际只能并发处理 10 个请求,多余连接会被拒绝,表现为偶发 502:
- 编辑
php/php-fpm.d/www.conf,调高:pm.max_children = 32 pm.start_servers = 8 pm.min_spare_servers = 4 pm.max_spare_servers = 12
- 确保
pm.max_children ≥ upstream keepalive × worker_processes;phpEnv 默认worker_processes 1,所以 32 ≥ 16 × 1 成立 - 改完执行
phpenv restart(或手动重启 php-fpm.exe 和 nginx.exe)
Windows 下特别容易失效的三个点
phpEnv 运行在 Windows,内核网络栈和 Linux 行为不同,以下配置不检查必踩坑:
- PHP-FPM 的
listen.backlog默认是511,但在 Windows 上实际生效值极低,建议显式设为128,否则新连接排队超时 - Nginx 的
worker_connections默认 512,但 Windows select() 模型性能差,别盲目调高;保持默认或设为256更稳 - 禁用
fastcgi_buffering off:Windows 下流式响应易中断长连接,保持 buffering on(默认)更可靠
真正起效的标志不是配置写完,而是用 netstat -an | findstr :9000 观察几分钟后仍有 10+ 个持续 ESTABLISHED 连接,且 PHP-FPM 的 slow.log 里不再频繁出现「connection reset by peer」——这才是长连接在干活。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











