用户登录

技术文章

外部链接将在新标签页打开。

Nginx 与 PHP-FPM 性能调优:先定位瓶颈,再改参数

一句话回答

调优的起点是确认瓶颈落在连接层还是进程层,而不是套用一组固定参数。Nginx 侧关注连接数上限、缓冲与上游复用,PHP-FPM 侧关注进程模型、子进程上限与超时链对齐;具体取值须由目标环境的压测与运行时指标确定,本文未执行任何压测或线上观测,不提供性能数字。

不存在一组可以跨环境复用的“最佳参数”。能复用的是一个顺序:先确认瓶颈在连接层还是进程层,再只改一个参数,最后用同一口径复核。本文给出参数含义、判定条件与定位顺序,不含性能数字。

本文的边界#

本次没有可用的正文素材,也没有执行压测或线上观测,因此不提供推荐数值、对比结果或“调优后提升多少”的结论。下文涉及的参数行为以你所装版本的官方文档为准,具体默认值与可用选项待核实。所有示例均为未执行的示例,只示意写法,数值为占位。

先分清两段:连接层与进程层#

Nginx 处理连接、TLS、静态资源与转发,PHP-FPM 是 FastCGI 进程池。同一个“变慢”可能来自 PHP 执行、进程池排队、连接建立或客户端本身。只盯 CPU 使用率容易把排队位置判断错。

Nginx 侧要看的几项

  • worker_processes:决定 worker 数量,通常与可用 CPU 相关;是否自动取值取决于你的版本,待核实。
  • worker_connections:单个 worker 的连接总数上限。反向代理场景下,与客户端的连接和与上游的连接都要占用名额,因此它不是“能接多少客户端”的直接数字。
  • 缓冲区大小:请求头、响应体的缓冲区调大可以少写临时文件,但会按并发数放大内存占用,不是单向收益。
  • 上游 keepalive:让 Nginx 复用与上游的连接,减少反复建连;是否支持及写法随版本不同,待核实。

PHP-FPM 侧要看的几项

  • pm:static 固定进程数,dynamic 按负载增减,ondemand 空闲时回收。选择取决于流量是否平稳,而不是哪个“更快”。
  • pm.max_children:子进程硬上限。打满后新请求进入排队等待,表现为延迟上升或网关超时,这是进程池机理,不是故障证据。
  • 超时链:request_terminate_timeout 与 Nginx 的 fastcgi_read_timeout 谁先触发,决定了超时后后端是否还在继续执行。两者需要按同一意图排序。
# 未执行示例:仅示意参数位置,数值为占位,不可直接用于生产
upstream php_backend {
    server unix:/run/php/php-fpm.sock;
    keepalive 待定;   # 需按版本确认是否支持
}
; 未执行示例:pool 配置片段,数值为占位
pm = dynamic
pm.max_children = 待定   ; 先按可用内存与单进程常驻内存估算,再用压测复核
request_terminate_timeout = 待定

一个可复核的单变量流程#

  1. 固定压测入口、请求类型和并发档位,记录一组基线指标。
  2. 根据观测提出一个假设,例如“瓶颈在进程池排队”。
  3. 一次只改一个参数,其余保持不动。
  4. 用同样的入口和口径复测,比较差异是否超出波动范围。
  5. 保留回滚方式,再进入下一个假设。

容易越界的三个地方#

  • 按内存估算子进程上限只是起点。用可用内存除以单进程常驻内存得到的是粗估,需以实际进程内存分布复核;单请求峰值内存与均值差别大时,粗估偏乐观。
  • 慢日志本身有开销。开启慢请求日志能定位长尾,但阈值设得过低会带来持续的写入负担,定位结束后应重新评估是否保留。
  • 缓冲区不是越大越好。放大单个连接的缓冲会按并发数放大总内存,收益与代价要在同一压测里一起看。

什么时候不该继续调参数#

如果单请求耗时主要消耗在数据库查询或外部接口调用上,调整 Nginx 与 PHP-FPM 只会改变排队发生的位置,不会缩短真正的处理时间。此时应先把外部依赖的耗时拆出来,再决定是否回到参数层。

作者:沐小悠

本文约 4 分钟读完 · 关键词:Nginx 调优、PHP-FPM 调优、pm.max_children、worker_connections、超时链

更多文章 GET 示例接口

「」标签下的其他文章