PHP-FPM 与 Nginx 保持长连接配置如何提升吞吐量?

文章导读
在 Nginx 配置中启用 fastcgi_keep_conn on; 可以让 Nginx 与 PHP-FPM 复用已建立的 FastCGI 连接,减少握手开销。适合高并发场景,但需确保 PHP-FPM 进程数充足,否则可能引发请求排队。
📋 目录
  1. 命令速用版
  2. 为什么会这样
  3. 分步处理
  4. 怎么验证是否生效
  5. 常见坑
  6. 常见问题
  7. 参考来源
A A

在 Nginx 配置中启用 fastcgi_keep_conn on; 可以让 Nginx 与 PHP-FPM 复用已建立的 FastCGI 连接,减少握手开销。适合高并发场景,但需确保 PHP-FPM 进程数充足,否则可能引发请求排队。

先说结论:开启长连接能降低单次请求延迟,提升单位时间处理能力,但依赖后端进程水位。

  • 先定位:确认当前瓶颈在 Nginx 与 PHP-FPM 的连接建立耗时,而非 PHP 代码执行耗时。
  • 先做:在 Nginx location 块添加 fastcgi_keep_conn on; 并调整 PHP-FPM pm 参数。
  • 再验证:通过压测工具观察请求延迟分布及错误率,公开资料中没有看到可靠的量化数据,需结合实际业务验证。

命令速用版

以下是 Nginx 配置片段,直接放入处理 PHP 请求的 location 块中:

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_keep_conn on;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
}

如果使用 Unix Socket,fastcgi_pass 改为 unix:/path/to/php-fpm.sock。

PHP-FPM 与 Nginx 保持长连接配置如何提升吞吐量?

为什么会这样

启用长连接的核心作用是减少 TCP 握手和 FastCGI 协议初始化的 CPU 开销。默认情况下,Nginx 处理完每个 PHP 请求后会关闭与 PHP-FPM 的连接,高并发时频繁创建销毁连接会消耗大量文件描述符和 CPU 时间。保持连接后,Nginx 可复用空闲连接,降低系统调用频率。

分步处理

按以下步骤操作,每步完成后检查状态再继续:

  1. 检查当前配置:查看 Nginx 配置中是否已有 fastcgi_keep_conn 指令,确认 PHP-FPM 监听方式(TCP 或 Socket)。
  2. 调整 PHP-FPM 进程数:编辑 php-fpm.conf 或 pool 配置,确保 pm.max_children 足够大,避免长连接占用导致无空闲进程。适用场景:高并发;风险边界:设置过大会耗尽内存。
  3. 应用 Nginx 配置:添加指令后执行 nginx -t 检查语法,确认无误后执行 nginx -s reload。
  4. 监控文件描述符:使用 lsof 或 ss 命令观察 Nginx 与 PHP-FPM 之间的连接状态,确认连接未异常堆积。

怎么验证是否生效

通过日志和监控工具确认连接复用情况及性能变化:

PHP-FPM 与 Nginx 保持长连接配置如何提升吞吐量?
  • 检查错误日志:查看 Nginx error.log 是否有 upstream prematurely closed connection 警告,减少此类日志说明连接稳定性提升。
  • 观察连接状态:使用命令 ss -anp | grep 9000 查看 TCP 连接状态,TIME_WAIT 数量应相对减少。
  • 压测对比:使用 wrk 或 ab 工具在相同并发下对比开启前后的延迟分布,关注 p99 延迟而非仅看平均值。

常见坑

  • PHP-FPM 进程不足:如果 pm.max_children 设置过小,长连接会占用空闲进程,导致新请求排队等待,反而降低吞吐量。
  • 脚本执行超时:长连接可能掩盖脚本执行慢的问题,需配合 request_terminate_timeout 使用,防止进程被长期占用。
  • Socket 权限问题:使用 Unix Socket 时,确保 Nginx 用户有权读写 sock 文件,否则长连接无法建立。

常见问题

使用 Unix Socket 还是 TCP 更好?

同机部署优先选 Unix Socket,开销更低;跨机部署必须用 TCP。长连接对两者均有效,但 Socket 避免了 TCP 协议栈开销。

开启长连接会导致内存泄漏吗?

不会直接导致泄漏,但会占用更多 PHP-FPM 进程驻留内存。需确保 pm.max_requests 设置合理,让进程定期重启释放内存。

Nginx 版本有要求吗?

需要 Nginx 1.1.11 及以上版本支持 fastcgi_keep_conn 指令,旧版本无法配置。

参考来源

  • Nginx 官方文档 - ngx_http_fastcgi_module: https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_keep_conn
  • PHP 官方手册 - FPM 配置:https://www.php.net/manual/en/install.fpm.configuration.php