云计算百科
云计算领域专业知识百科平台

PHP 生命周期与 PHP-FPM 工作模式:从 Nginx 到 PHP 执行完毕的全链路剖析

目录

  • 1. 引言:为什么需要理解 PHP 的生命周期
  • 2. 先建立整体认知:三个角色
  • 3. 一次请求的完整生命周期
    • 3.1 阶段一:Nginx 接收请求
    • 3.2 阶段二:FastCGI 协议封装
    • 3.3 阶段三:PHP-FPM 调度到 Worker
    • 3.4 阶段四:响应回传
  • 4. PHP-FPM 的进程模型
    • 4.1 Master / Worker 双层结构
    • 4.2 三种进程管理策略
    • 4.3 为什么 PHP 不需要连接池
  • 5. 与 Java 常驻模型的本质差异
  • 6. 全链路时序图
  • 7. 实践建议
  • 8. 小结

1. 引言:为什么需要理解 PHP 的生命周期

很多同学写 PHP 时,习惯把 PHP 当成"脚本语言"来理解:写完一个 index.php,丢到服务器上,浏览器一访问就出结果。但一旦遇到线上问题——比如"为什么 PHP 没有像 Java 那样的连接池"、“为什么 static 变量在两次请求之间不共享”、“为什么 PHP-FPM 进程数调大反而更慢”——就会发现,不理解生命周期和进程模型,很多现象根本解释不通。

本文从一次 HTTP 请求出发,把「Nginx → FastCGI → PHP-FPM → PHP 脚本执行 → 响应返回」这条链路完整拆开,并重点对比 PHP-FPM 的常驻进程模型 与 Java 常驻应用模型 的本质差异,最后给出一张全链路时序图,方便你建立整体认知。

2. 先建立整体认知:三个角色

在典型的 LNMP 架构中,一次 PHP 请求会经过三个核心角色:

角色职责是否常驻
Nginx 接收 HTTP 请求、静态资源直接返回、动态请求转发给 PHP-FPM 常驻(Master + Worker)
PHP-FPM 管理一组 PHP 进程,接收 FastCGI 协议请求并调度给 Worker 常驻(Master + Pool Worker)
PHP 解释器 在 Worker 进程内解析并执行 PHP 脚本 随 Worker 常驻,但每次请求重新初始化脚本上下文

关键点在于:PHP-FPM 的进程是常驻的,但 PHP 的"应用状态"不是常驻的。这是理解后面所有差异的钥匙。

下面用一张图把三个角色的关系与数据流向串起来:

#mermaid-svg-HGdyoq5cuEL98zWl{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-HGdyoq5cuEL98zWl .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-HGdyoq5cuEL98zWl .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-HGdyoq5cuEL98zWl .error-icon{fill:#552222;}#mermaid-svg-HGdyoq5cuEL98zWl .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-HGdyoq5cuEL98zWl .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-HGdyoq5cuEL98zWl .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-HGdyoq5cuEL98zWl .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-HGdyoq5cuEL98zWl .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-HGdyoq5cuEL98zWl .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-HGdyoq5cuEL98zWl .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-HGdyoq5cuEL98zWl .marker{fill:#333333;stroke:#333333;}#mermaid-svg-HGdyoq5cuEL98zWl .marker.cross{stroke:#333333;}#mermaid-svg-HGdyoq5cuEL98zWl svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-HGdyoq5cuEL98zWl p{margin:0;}#mermaid-svg-HGdyoq5cuEL98zWl .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-HGdyoq5cuEL98zWl .cluster-label text{fill:#333;}#mermaid-svg-HGdyoq5cuEL98zWl .cluster-label span{color:#333;}#mermaid-svg-HGdyoq5cuEL98zWl .cluster-label span p{background-color:transparent;}#mermaid-svg-HGdyoq5cuEL98zWl .label text,#mermaid-svg-HGdyoq5cuEL98zWl span{fill:#333;color:#333;}#mermaid-svg-HGdyoq5cuEL98zWl .node rect,#mermaid-svg-HGdyoq5cuEL98zWl .node circle,#mermaid-svg-HGdyoq5cuEL98zWl .node ellipse,#mermaid-svg-HGdyoq5cuEL98zWl .node polygon,#mermaid-svg-HGdyoq5cuEL98zWl .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-HGdyoq5cuEL98zWl .rough-node .label text,#mermaid-svg-HGdyoq5cuEL98zWl .node .label text,#mermaid-svg-HGdyoq5cuEL98zWl .image-shape .label,#mermaid-svg-HGdyoq5cuEL98zWl .icon-shape .label{text-anchor:middle;}#mermaid-svg-HGdyoq5cuEL98zWl .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-HGdyoq5cuEL98zWl .rough-node .label,#mermaid-svg-HGdyoq5cuEL98zWl .node .label,#mermaid-svg-HGdyoq5cuEL98zWl .image-shape .label,#mermaid-svg-HGdyoq5cuEL98zWl .icon-shape .label{text-align:center;}#mermaid-svg-HGdyoq5cuEL98zWl .node.clickable{cursor:pointer;}#mermaid-svg-HGdyoq5cuEL98zWl .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-HGdyoq5cuEL98zWl .arrowheadPath{fill:#333333;}#mermaid-svg-HGdyoq5cuEL98zWl .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-HGdyoq5cuEL98zWl .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-HGdyoq5cuEL98zWl .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HGdyoq5cuEL98zWl .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-HGdyoq5cuEL98zWl .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HGdyoq5cuEL98zWl .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-HGdyoq5cuEL98zWl .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-HGdyoq5cuEL98zWl .cluster text{fill:#333;}#mermaid-svg-HGdyoq5cuEL98zWl .cluster span{color:#333;}#mermaid-svg-HGdyoq5cuEL98zWl div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-HGdyoq5cuEL98zWl .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-HGdyoq5cuEL98zWl rect.text{fill:none;stroke-width:0;}#mermaid-svg-HGdyoq5cuEL98zWl .icon-shape,#mermaid-svg-HGdyoq5cuEL98zWl .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-HGdyoq5cuEL98zWl .icon-shape p,#mermaid-svg-HGdyoq5cuEL98zWl .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-HGdyoq5cuEL98zWl .icon-shape .label rect,#mermaid-svg-HGdyoq5cuEL98zWl .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-HGdyoq5cuEL98zWl .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-HGdyoq5cuEL98zWl .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-HGdyoq5cuEL98zWl :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

HTTP 请求

静态资源直接返回

FastCGI 协议

FCGI_STDOUT

响应

HTTP 响应

浏览器

Nginx(Master + Worker)

PHP-FPM(Master + Worker 池)

PHP 解释器 / OPcache

3. 一次请求的完整生命周期

3.1 阶段一:Nginx 接收请求

浏览器发起 GET /index.php?id=1,Nginx 的 Master 进程早已监听 80/443 端口,连接建立后由某个 Worker 进程接管。Nginx Worker 根据 location 配置判断:

  • 静态文件(.css、.js、图片)→ 直接读磁盘返回;
  • .php 结尾 → 交给 fastcgi_pass 指定的上游,也就是 PHP-FPM 监听的地址(Unix Socket 或 127.0.0.1:9000)。

location ~ \\.php$ {
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}

3.2 阶段二:FastCGI 协议封装

Nginx 不会直接"调用" PHP,而是把 HTTP 请求翻译成 FastCGI 协议的二进制报文。FastCGI 是一种二进制协议,报文由「Header + Body」组成,常见类型有:

  • FCGI_BEGIN_REQUEST:开始一次请求;
  • FCGI_PARAMS:传递 QUERY_STRING、REQUEST_METHOD、SCRIPT_FILENAME 等参数;
  • FCGI_STDIN:请求体(POST 数据);
  • FCGI_STDOUT / FCGI_STDERR:PHP 的输出与错误。

相比 CGI 每次请求 fork 一个新进程,FastCGI 的核心优势就是进程复用:一个进程可以连续处理多个请求,省去反复 fork 和加载解释器的开销。

3.3 阶段三:PHP-FPM 调度到 Worker

PHP-FPM 的 Master 进程收到连接后,从进程池中挑一个空闲 Worker,把请求交给它。Worker 进程内部大致做这些事:

  • 读取并解析 FastCGI 报文,还原出 $_GET、$_POST、$_SERVER 等超全局变量;
  • 初始化请求上下文:重置符号表、清空上一次请求残留的全局变量、设置 max_execution_time 计时器;
  • 编译并执行脚本:如果开启了 OPcache,会先查缓存,命中则跳过词法/语法分析,直接执行 opcode;
  • 输出缓冲:echo 的内容先进入输出缓冲区,按 output_buffering 配置决定何时刷出;
  • 请求收尾:执行 register_shutdown_function 注册的回调、调用析构函数、关闭数据库连接、释放内存(memory_limit 检查贯穿全程)。
  • 3.4 阶段四:响应回传

    Worker 把输出通过 FCGI_STDOUT 写回 Nginx,Nginx 再组装成标准 HTTP 响应(补上状态行、响应头)返回给浏览器。至此一次请求结束,Worker 进程并不退出,而是回到空闲状态等待下一个请求。

    把四个阶段串成一条状态流转,可以更直观地看到请求在链路中的推进:

    #mermaid-svg-8OhfRqLeHM1BogbD{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-8OhfRqLeHM1BogbD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-8OhfRqLeHM1BogbD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-8OhfRqLeHM1BogbD .error-icon{fill:#552222;}#mermaid-svg-8OhfRqLeHM1BogbD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-8OhfRqLeHM1BogbD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-8OhfRqLeHM1BogbD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-8OhfRqLeHM1BogbD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-8OhfRqLeHM1BogbD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-8OhfRqLeHM1BogbD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-8OhfRqLeHM1BogbD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-8OhfRqLeHM1BogbD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-8OhfRqLeHM1BogbD .marker.cross{stroke:#333333;}#mermaid-svg-8OhfRqLeHM1BogbD svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-8OhfRqLeHM1BogbD p{margin:0;}#mermaid-svg-8OhfRqLeHM1BogbD .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-8OhfRqLeHM1BogbD .cluster-label text{fill:#333;}#mermaid-svg-8OhfRqLeHM1BogbD .cluster-label span{color:#333;}#mermaid-svg-8OhfRqLeHM1BogbD .cluster-label span p{background-color:transparent;}#mermaid-svg-8OhfRqLeHM1BogbD .label text,#mermaid-svg-8OhfRqLeHM1BogbD span{fill:#333;color:#333;}#mermaid-svg-8OhfRqLeHM1BogbD .node rect,#mermaid-svg-8OhfRqLeHM1BogbD .node circle,#mermaid-svg-8OhfRqLeHM1BogbD .node ellipse,#mermaid-svg-8OhfRqLeHM1BogbD .node polygon,#mermaid-svg-8OhfRqLeHM1BogbD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-8OhfRqLeHM1BogbD .rough-node .label text,#mermaid-svg-8OhfRqLeHM1BogbD .node .label text,#mermaid-svg-8OhfRqLeHM1BogbD .image-shape .label,#mermaid-svg-8OhfRqLeHM1BogbD .icon-shape .label{text-anchor:middle;}#mermaid-svg-8OhfRqLeHM1BogbD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-8OhfRqLeHM1BogbD .rough-node .label,#mermaid-svg-8OhfRqLeHM1BogbD .node .label,#mermaid-svg-8OhfRqLeHM1BogbD .image-shape .label,#mermaid-svg-8OhfRqLeHM1BogbD .icon-shape .label{text-align:center;}#mermaid-svg-8OhfRqLeHM1BogbD .node.clickable{cursor:pointer;}#mermaid-svg-8OhfRqLeHM1BogbD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-8OhfRqLeHM1BogbD .arrowheadPath{fill:#333333;}#mermaid-svg-8OhfRqLeHM1BogbD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-8OhfRqLeHM1BogbD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-8OhfRqLeHM1BogbD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8OhfRqLeHM1BogbD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-8OhfRqLeHM1BogbD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8OhfRqLeHM1BogbD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-8OhfRqLeHM1BogbD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-8OhfRqLeHM1BogbD .cluster text{fill:#333;}#mermaid-svg-8OhfRqLeHM1BogbD .cluster span{color:#333;}#mermaid-svg-8OhfRqLeHM1BogbD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-8OhfRqLeHM1BogbD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-8OhfRqLeHM1BogbD rect.text{fill:none;stroke-width:0;}#mermaid-svg-8OhfRqLeHM1BogbD .icon-shape,#mermaid-svg-8OhfRqLeHM1BogbD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-8OhfRqLeHM1BogbD .icon-shape p,#mermaid-svg-8OhfRqLeHM1BogbD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-8OhfRqLeHM1BogbD .icon-shape .label rect,#mermaid-svg-8OhfRqLeHM1BogbD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-8OhfRqLeHM1BogbD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-8OhfRqLeHM1BogbD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-8OhfRqLeHM1BogbD :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    下一个请求

    阶段一:Nginx 接收请求

    阶段二:FastCGI 协议封装

    阶段三:PHP-FPM 调度到 Worker

    阶段四:响应回传

    Worker 回到空闲,等待下一请求

    4. PHP-FPM 的进程模型

    4.1 Master / Worker 双层结构

    #mermaid-svg-QYTFQfcrus24KKO4{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QYTFQfcrus24KKO4 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QYTFQfcrus24KKO4 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QYTFQfcrus24KKO4 .error-icon{fill:#552222;}#mermaid-svg-QYTFQfcrus24KKO4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QYTFQfcrus24KKO4 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QYTFQfcrus24KKO4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QYTFQfcrus24KKO4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QYTFQfcrus24KKO4 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QYTFQfcrus24KKO4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QYTFQfcrus24KKO4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QYTFQfcrus24KKO4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QYTFQfcrus24KKO4 .marker.cross{stroke:#333333;}#mermaid-svg-QYTFQfcrus24KKO4 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QYTFQfcrus24KKO4 p{margin:0;}#mermaid-svg-QYTFQfcrus24KKO4 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-QYTFQfcrus24KKO4 .cluster-label text{fill:#333;}#mermaid-svg-QYTFQfcrus24KKO4 .cluster-label span{color:#333;}#mermaid-svg-QYTFQfcrus24KKO4 .cluster-label span p{background-color:transparent;}#mermaid-svg-QYTFQfcrus24KKO4 .label text,#mermaid-svg-QYTFQfcrus24KKO4 span{fill:#333;color:#333;}#mermaid-svg-QYTFQfcrus24KKO4 .node rect,#mermaid-svg-QYTFQfcrus24KKO4 .node circle,#mermaid-svg-QYTFQfcrus24KKO4 .node ellipse,#mermaid-svg-QYTFQfcrus24KKO4 .node polygon,#mermaid-svg-QYTFQfcrus24KKO4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QYTFQfcrus24KKO4 .rough-node .label text,#mermaid-svg-QYTFQfcrus24KKO4 .node .label text,#mermaid-svg-QYTFQfcrus24KKO4 .image-shape .label,#mermaid-svg-QYTFQfcrus24KKO4 .icon-shape .label{text-anchor:middle;}#mermaid-svg-QYTFQfcrus24KKO4 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QYTFQfcrus24KKO4 .rough-node .label,#mermaid-svg-QYTFQfcrus24KKO4 .node .label,#mermaid-svg-QYTFQfcrus24KKO4 .image-shape .label,#mermaid-svg-QYTFQfcrus24KKO4 .icon-shape .label{text-align:center;}#mermaid-svg-QYTFQfcrus24KKO4 .node.clickable{cursor:pointer;}#mermaid-svg-QYTFQfcrus24KKO4 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QYTFQfcrus24KKO4 .arrowheadPath{fill:#333333;}#mermaid-svg-QYTFQfcrus24KKO4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QYTFQfcrus24KKO4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QYTFQfcrus24KKO4 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QYTFQfcrus24KKO4 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QYTFQfcrus24KKO4 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QYTFQfcrus24KKO4 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QYTFQfcrus24KKO4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QYTFQfcrus24KKO4 .cluster text{fill:#333;}#mermaid-svg-QYTFQfcrus24KKO4 .cluster span{color:#333;}#mermaid-svg-QYTFQfcrus24KKO4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QYTFQfcrus24KKO4 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QYTFQfcrus24KKO4 rect.text{fill:none;stroke-width:0;}#mermaid-svg-QYTFQfcrus24KKO4 .icon-shape,#mermaid-svg-QYTFQfcrus24KKO4 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QYTFQfcrus24KKO4 .icon-shape p,#mermaid-svg-QYTFQfcrus24KKO4 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QYTFQfcrus24KKO4 .icon-shape .label rect,#mermaid-svg-QYTFQfcrus24KKO4 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QYTFQfcrus24KKO4 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QYTFQfcrus24KKO4 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QYTFQfcrus24KKO4 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    PHP-FPM Master 进程

    Worker 进程 1

    Worker 进程 2

    Worker 进程 N

    处理请求 / 空闲等待

    监听信号 / 平滑重载 / 进程管理

    • Master 进程:只负责管理,不处理请求。监听 SIGUSR2 做平滑重载、SIGQUIT 优雅退出,根据 pm 策略动态增减 Worker。
    • Worker 进程:真正干活的进程,每个进程同一时刻只处理一个请求(单线程同步模型)。

    4.2 三种进程管理策略

    策略说明适用场景
    static 固定数量 Worker,启动即创建 流量稳定、追求低延迟
    dynamic 空闲时缩容,繁忙时扩容,有 start_servers / min_spare_servers / max_spare_servers 大多数通用场景
    ondemand 有请求才创建 Worker,空闲一段时间后销毁 低流量、内存敏感场景

    pm = dynamic
    pm.max_children = 50
    pm.start_servers = 10
    pm.min_spare_servers = 5
    pm.max_spare_servers = 20
    pm.max_requests = 500

    其中 pm.max_requests 很关键:Worker 处理满 N 个请求后自动退出并由 Master 重建,用来规避第三方扩展的内存泄漏。

    三种策略在进程数量随流量变化上的差异,可以用下图对比:

    #mermaid-svg-OSGBTKPwjCUPciwT{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OSGBTKPwjCUPciwT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OSGBTKPwjCUPciwT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OSGBTKPwjCUPciwT .error-icon{fill:#552222;}#mermaid-svg-OSGBTKPwjCUPciwT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OSGBTKPwjCUPciwT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OSGBTKPwjCUPciwT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OSGBTKPwjCUPciwT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OSGBTKPwjCUPciwT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OSGBTKPwjCUPciwT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OSGBTKPwjCUPciwT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OSGBTKPwjCUPciwT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OSGBTKPwjCUPciwT .marker.cross{stroke:#333333;}#mermaid-svg-OSGBTKPwjCUPciwT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OSGBTKPwjCUPciwT p{margin:0;}#mermaid-svg-OSGBTKPwjCUPciwT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-OSGBTKPwjCUPciwT .cluster-label text{fill:#333;}#mermaid-svg-OSGBTKPwjCUPciwT .cluster-label span{color:#333;}#mermaid-svg-OSGBTKPwjCUPciwT .cluster-label span p{background-color:transparent;}#mermaid-svg-OSGBTKPwjCUPciwT .label text,#mermaid-svg-OSGBTKPwjCUPciwT span{fill:#333;color:#333;}#mermaid-svg-OSGBTKPwjCUPciwT .node rect,#mermaid-svg-OSGBTKPwjCUPciwT .node circle,#mermaid-svg-OSGBTKPwjCUPciwT .node ellipse,#mermaid-svg-OSGBTKPwjCUPciwT .node polygon,#mermaid-svg-OSGBTKPwjCUPciwT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OSGBTKPwjCUPciwT .rough-node .label text,#mermaid-svg-OSGBTKPwjCUPciwT .node .label text,#mermaid-svg-OSGBTKPwjCUPciwT .image-shape .label,#mermaid-svg-OSGBTKPwjCUPciwT .icon-shape .label{text-anchor:middle;}#mermaid-svg-OSGBTKPwjCUPciwT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OSGBTKPwjCUPciwT .rough-node .label,#mermaid-svg-OSGBTKPwjCUPciwT .node .label,#mermaid-svg-OSGBTKPwjCUPciwT .image-shape .label,#mermaid-svg-OSGBTKPwjCUPciwT .icon-shape .label{text-align:center;}#mermaid-svg-OSGBTKPwjCUPciwT .node.clickable{cursor:pointer;}#mermaid-svg-OSGBTKPwjCUPciwT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OSGBTKPwjCUPciwT .arrowheadPath{fill:#333333;}#mermaid-svg-OSGBTKPwjCUPciwT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OSGBTKPwjCUPciwT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OSGBTKPwjCUPciwT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OSGBTKPwjCUPciwT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OSGBTKPwjCUPciwT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OSGBTKPwjCUPciwT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OSGBTKPwjCUPciwT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OSGBTKPwjCUPciwT .cluster text{fill:#333;}#mermaid-svg-OSGBTKPwjCUPciwT .cluster span{color:#333;}#mermaid-svg-OSGBTKPwjCUPciwT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OSGBTKPwjCUPciwT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OSGBTKPwjCUPciwT rect.text{fill:none;stroke-width:0;}#mermaid-svg-OSGBTKPwjCUPciwT .icon-shape,#mermaid-svg-OSGBTKPwjCUPciwT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OSGBTKPwjCUPciwT .icon-shape p,#mermaid-svg-OSGBTKPwjCUPciwT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OSGBTKPwjCUPciwT .icon-shape .label rect,#mermaid-svg-OSGBTKPwjCUPciwT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OSGBTKPwjCUPciwT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OSGBTKPwjCUPciwT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OSGBTKPwjCUPciwT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    ondemand:有请求才创建

    空闲 → 销毁 Worker

    有请求 → 新建 Worker

    dynamic:按需伸缩

    流量低 → 缩容至 min_spare

    流量高 → 扩容至 max_children

    static:固定数量

    流量低 → Worker 数不变

    流量高 → Worker 数不变

    4.3 为什么 PHP 不需要连接池

    因为每个 Worker 是同步阻塞处理请求的,一个进程同一时刻只服务一个请求,所以进程内的数据库连接天然不会被并发争用。这也是为什么 PHP 里"连接池"通常要靠 pgbouncer、ProxySQL 这类外部组件,而不是像 Java 那样在应用内维护 HikariCP。

    5. 与 Java 常驻模型的本质差异

    很多人把"PHP-FPM 进程常驻"和"Java 应用常驻"混为一谈,其实两者常驻的粒度完全不同。

    维度PHP-FPMJava(Spring Boot 等)
    常驻对象 进程常驻,应用状态不常驻 进程常驻,应用状态常驻
    请求处理 每请求重建脚本上下文 同一 JVM 内多线程共享堆内存
    并发模型 多进程 + 同步阻塞 单进程多线程(或协程)
    内存共享 进程间不共享(除 OPcache 共享内存) 线程间共享堆对象
    连接池 一般无(靠外部中间件) 应用内连接池(HikariCP 等)
    热更新 reload 平滑重启 Worker 需重启或借助热部署工具
    内存泄漏影响 单 Worker 泄漏,max_requests 可兜底 整个 JVM 受影响,可能 OOM

    一句话总结:PHP-FPM 常驻的是"执行环境",Java 常驻的是"应用实例"。PHP 每次请求都从"干净"的状态开始,这既是它的简单之处,也是它无法做进程内缓存、连接池、长连接推送的根本原因。

    从请求处理的角度看,两者的差异可以这样对照:

    #mermaid-svg-jY82Dm7QrayRK30v{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-jY82Dm7QrayRK30v .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-jY82Dm7QrayRK30v .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-jY82Dm7QrayRK30v .error-icon{fill:#552222;}#mermaid-svg-jY82Dm7QrayRK30v .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jY82Dm7QrayRK30v .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-jY82Dm7QrayRK30v .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jY82Dm7QrayRK30v .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jY82Dm7QrayRK30v .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-jY82Dm7QrayRK30v .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jY82Dm7QrayRK30v .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jY82Dm7QrayRK30v .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jY82Dm7QrayRK30v .marker.cross{stroke:#333333;}#mermaid-svg-jY82Dm7QrayRK30v svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jY82Dm7QrayRK30v p{margin:0;}#mermaid-svg-jY82Dm7QrayRK30v .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-jY82Dm7QrayRK30v .cluster-label text{fill:#333;}#mermaid-svg-jY82Dm7QrayRK30v .cluster-label span{color:#333;}#mermaid-svg-jY82Dm7QrayRK30v .cluster-label span p{background-color:transparent;}#mermaid-svg-jY82Dm7QrayRK30v .label text,#mermaid-svg-jY82Dm7QrayRK30v span{fill:#333;color:#333;}#mermaid-svg-jY82Dm7QrayRK30v .node rect,#mermaid-svg-jY82Dm7QrayRK30v .node circle,#mermaid-svg-jY82Dm7QrayRK30v .node ellipse,#mermaid-svg-jY82Dm7QrayRK30v .node polygon,#mermaid-svg-jY82Dm7QrayRK30v .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jY82Dm7QrayRK30v .rough-node .label text,#mermaid-svg-jY82Dm7QrayRK30v .node .label text,#mermaid-svg-jY82Dm7QrayRK30v .image-shape .label,#mermaid-svg-jY82Dm7QrayRK30v .icon-shape .label{text-anchor:middle;}#mermaid-svg-jY82Dm7QrayRK30v .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-jY82Dm7QrayRK30v .rough-node .label,#mermaid-svg-jY82Dm7QrayRK30v .node .label,#mermaid-svg-jY82Dm7QrayRK30v .image-shape .label,#mermaid-svg-jY82Dm7QrayRK30v .icon-shape .label{text-align:center;}#mermaid-svg-jY82Dm7QrayRK30v .node.clickable{cursor:pointer;}#mermaid-svg-jY82Dm7QrayRK30v .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-jY82Dm7QrayRK30v .arrowheadPath{fill:#333333;}#mermaid-svg-jY82Dm7QrayRK30v .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jY82Dm7QrayRK30v .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jY82Dm7QrayRK30v .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jY82Dm7QrayRK30v .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-jY82Dm7QrayRK30v .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jY82Dm7QrayRK30v .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-jY82Dm7QrayRK30v .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jY82Dm7QrayRK30v .cluster text{fill:#333;}#mermaid-svg-jY82Dm7QrayRK30v .cluster span{color:#333;}#mermaid-svg-jY82Dm7QrayRK30v div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jY82Dm7QrayRK30v .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-jY82Dm7QrayRK30v rect.text{fill:none;stroke-width:0;}#mermaid-svg-jY82Dm7QrayRK30v .icon-shape,#mermaid-svg-jY82Dm7QrayRK30v .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-jY82Dm7QrayRK30v .icon-shape p,#mermaid-svg-jY82Dm7QrayRK30v .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-jY82Dm7QrayRK30v .icon-shape .label rect,#mermaid-svg-jY82Dm7QrayRK30v .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-jY82Dm7QrayRK30v .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-jY82Dm7QrayRK30v .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-jY82Dm7QrayRK30v :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Java:进程常驻,状态常驻

    请求进入

    复用 JVM 堆内对象

    线程处理业务

    请求结束,对象仍存活

    PHP-FPM:进程常驻,状态不常驻

    请求进入

    重建脚本上下文

    执行脚本

    请求结束,状态销毁

    6. 全链路时序图

    "PHP 脚本 / OPcache"

    "PHP-FPM Worker"

    "PHP-FPM Master"

    "Nginx Worker"

    "浏览器"

    "PHP 脚本 / OPcache"

    "PHP-FPM Worker"

    "PHP-FPM Master"

    "Nginx Worker"

    "浏览器"

    #mermaid-svg-dqiENUr9UDg26TN7{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-dqiENUr9UDg26TN7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-dqiENUr9UDg26TN7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-dqiENUr9UDg26TN7 .error-icon{fill:#552222;}#mermaid-svg-dqiENUr9UDg26TN7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dqiENUr9UDg26TN7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-dqiENUr9UDg26TN7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dqiENUr9UDg26TN7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dqiENUr9UDg26TN7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-dqiENUr9UDg26TN7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dqiENUr9UDg26TN7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dqiENUr9UDg26TN7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dqiENUr9UDg26TN7 .marker.cross{stroke:#333333;}#mermaid-svg-dqiENUr9UDg26TN7 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dqiENUr9UDg26TN7 p{margin:0;}#mermaid-svg-dqiENUr9UDg26TN7 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-dqiENUr9UDg26TN7 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-dqiENUr9UDg26TN7 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-dqiENUr9UDg26TN7 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-dqiENUr9UDg26TN7 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-dqiENUr9UDg26TN7 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-dqiENUr9UDg26TN7 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-dqiENUr9UDg26TN7 .sequenceNumber{fill:white;}#mermaid-svg-dqiENUr9UDg26TN7 #sequencenumber{fill:#333;}#mermaid-svg-dqiENUr9UDg26TN7 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-dqiENUr9UDg26TN7 .messageText{fill:#333;stroke:none;}#mermaid-svg-dqiENUr9UDg26TN7 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-dqiENUr9UDg26TN7 .labelText,#mermaid-svg-dqiENUr9UDg26TN7 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-dqiENUr9UDg26TN7 .loopText,#mermaid-svg-dqiENUr9UDg26TN7 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-dqiENUr9UDg26TN7 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-dqiENUr9UDg26TN7 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-dqiENUr9UDg26TN7 .noteText,#mermaid-svg-dqiENUr9UDg26TN7 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-dqiENUr9UDg26TN7 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-dqiENUr9UDg26TN7 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-dqiENUr9UDg26TN7 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-dqiENUr9UDg26TN7 .actorPopupMenu{position:absolute;}#mermaid-svg-dqiENUr9UDg26TN7 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-dqiENUr9UDg26TN7 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-dqiENUr9UDg26TN7 .actor-man circle,#mermaid-svg-dqiENUr9UDg26TN7 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-dqiENUr9UDg26TN7 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    "Worker 不退出,回到空闲等待下一个请求"

    "HTTP GET /index.php"

    "匹配 location,判断为动态请求"

    "FastCGI 连接(Unix Socket / TCP)"

    "调度空闲 Worker"

    "解析 FCGI_PARAMS,构建超全局变量"

    "初始化请求上下文"

    "OPcache 命中则直接执行 opcode"

    "输出写入缓冲区"

    "FCGI_STDOUT 回传"

    "组装 HTTP 响应返回"

    "请求收尾:析构、关连接、释放内存"

    7. 实践建议

  • 合理设置 pm.max_children:按 可用内存 / 单进程内存 估算,盲目调大会导致内存 swap,反而拖慢整体。
  • 开启 OPcache:opcache.enable=1、opcache.validate_timestamps=0(生产环境配合发布时 reload),能显著减少编译开销。
  • 用 pm.max_requests 兜底内存泄漏:尤其是用了老旧扩展的项目。
  • 不要在 PHP 里做进程内缓存:static 变量、全局数组在请求结束后都会销毁,需要缓存请用 Redis / Memcached。
  • 长耗时任务交给队列:PHP-FPM Worker 数量有限,同步执行耗时任务会迅速耗尽进程池。
  • 8. 小结

    理解 PHP 生命周期,核心就三句话:

    • Nginx 负责接入与转发,FastCGI 负责协议转换,PHP-FPM 负责进程调度,PHP 解释器负责执行;
    • 进程常驻,但应用状态不常驻,每次请求都是一次"干净的初始化";
    • 与 Java 的差异不在"是否常驻",而在常驻的粒度——这决定了连接池、缓存、并发模型等一系列设计取舍。

    把这条链路在脑子里跑通,再遇到"PHP 为什么慢"“进程数怎么调”"为什么没有连接池"这类问题,就能从根上解释了。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » PHP 生命周期与 PHP-FPM 工作模式:从 Nginx 到 PHP 执行完毕的全链路剖析
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!