温馨提示×

php-fpm在Linux中的进程模型是怎样的

小樊
36
2025-12-22 04:38:11
栏目: 编程语言

架构与进程角色

  • 采用 master/worker 多进程模型:由 1 个 master 进程负责进程生命周期、配置加载、信号与事件循环管理;由 N 个 worker 进程负责实际的 PHP 请求处理。worker 由 master fork 产生,继承监听套接字,形成进程池。worker 进程是 单线程、同步阻塞 的模型,同一时刻通常只处理 1 个请求,处理完再继续等待下一个连接。master 与 worker 之间通过 共享内存维护状态,master 通过 信号控制 worker 的退出与回收。

请求处理流程

  • 监听与接收:worker 进程在 listening socket 上阻塞等待连接(accept)。新连接到来时,内核只会唤醒 一个 worker(避免“惊群”)。worker 读取 FastCGI 协议流并处理请求,完成后返回进程池继续等待。
  • 标准 I/O 重定向:master 将自身的 STDIN/STDOUT 重定向到 /dev/nullSTDERR 重定向到 error_log;worker 的 STDIN 接到 listening socket,STDOUT/STDERR 可重定向到管道,master 通过 reactor 监听并写入日志(受 catch_workers_output 影响)。
  • 生命周期:请求进入后经历 接收 → 解析与执行(Zend 引擎) → 结束清理 三个阶段,释放本次请求占用的资源,然后继续循环等待。

进程管理与调度

  • 三种管理模式(由 pm 配置):
    • static:启动时一次性 fork 出 pm.max_children 个 worker,运行中不再增减,适合负载稳定、追求低开销的场景。
    • dynamic:启动时创建 pm.start_servers 个 worker,随后由定时心跳维护空闲进程数:少于 pm.min_spare_servers 则 fork,多于 pm.max_spare_servers 则回收;上限为 pm.max_children,适合请求量波动较大的场景。
    • ondemand:启动时不创建 worker,有请求时按需 fork;空闲超过 pm.process_idle_timeout 的 worker 会被回收,适合内存紧张且请求量较小的场景。
  • 典型参数与作用(示例):
    • pm.max_children:最大 worker 数(static 的有效值;dynamic 的上限)。
    • pm.start_servers:启动时 worker 数(dynamic/ondemand 有效)。
    • pm.min_spare_servers / pm.max_spare_servers:空闲 worker 的最小/最大数(dynamic 有效)。
    • pm.process_idle_timeout:空闲超时回收时间(ondemand 有效)。

与 Nginx 的协作与通信

  • 常见部署中,Nginx 作为反向代理,将 PHP 请求通过 FastCGI 转发给 PHP-FPM。通信方式有两种:
    • Unix domain socket:同机进程间通信,路径如 /run/php/phpX.Y-fpm.sock,省去网络协议栈开销,性能略优。
    • TCP socket:如 127.0.0.1:9000,可跨机通信,稳定性与通用性更好。
  • 请求并非由 master “转发”,而是由 worker 直接 accept 并处理;master 只负责进程管理与信号控制。

运维与调优要点

  • 进程数估算:先评估单个 worker 的内存占用(含扩展与业务),用“可用内存/单进程内存”粗估 pm.max_children,并预留内存给系统与其他服务。
  • 模式选择:负载稳定、并发较高时倾向 static;波动明显时选 dynamic;内存紧张且低峰期很长时再考虑 ondemand(注意按需创建带来的冷启动与 CPU 抖动)。
  • 稳定性与自恢复:设置 pm.max_requests 定期重启 worker,缓解潜在内存泄漏;开启 slowlog 与合理的 request_terminate_timeout,定位慢请求与超时问题。

0