解析php-fpm

184 阅读4分钟

概念

Fpm是一种多进程模型的进程管理器,它由一个master进程和多个worker进程组成。

master

  • master进程的负责fork或者杀掉worker进程
  • master在调用完fpm_run()后不再返回,而是进入一个事件循环中.

worker

worker进程不断Accept请求,有请求到达后将读取并解析FastCGI协议的数据,解析完成后开始执行PHP脚本,执行完成后关闭请求。

fpm处理流程

  • fpm启动调用各个扩展的mint方法,进行初始化(数据的初始化)
  • 请求过来,执行rint对单个请求进行一个初始化(请求的初始化)
  • 执行php脚本
  • 执行rshutdown方法(结果响应)
  • 停止fpm,执行mshutdown

Nginx 与 php-fpm 运行流程

  • nginx根据配置文件加载fast-cgi模块
  • php-fpm监听9000端口
  • php-fpm端口接收到请求,启用worker进程处理请求
  • 处理完请求,返回nginx
  • nginx讲结果通过http返回到浏览器

三种进程管理方式

  • 静态模式(static):启动时master根据pm.max_children配置fork出响应数量的worker进程,worker进程数固定
  • 动态模式(dynamic):启动时根据pm.start_servers配置初始化的数量的worker. 运行期间master发现空闲的worker进程少了会在max_children的数量下进行fork,当空闲的worker进程多了,会讲worker进程杀掉一些。(min\max_spare_servers)
  • 按需模式(ondemand):启动时不分配worker进程,等有请求了后再fork worker进程。处理完成后worker不会立即退出,当空闲时间超过pm.process_idle_timeout后再进行退出。

参数设置

  • 一般来说一台服务器正常情况下每一个php-cgi所耗费的内存在20M~30M左右
# 查看 php-fpm的平均内存消耗
ps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'

#查看php-fpm的进程个数
ps -ef |grep "php-fpm"|grep "pool"|wc -l

# 内存消耗明细
pmap $(pgrep php-fpm) | less


  • max_children较好的设置方式根据req/s(吞吐率,单位时间里服务器处理的最大请求数,单位req/s)来设置,若程序是 100 req/s 的处理能力,那么就设置 100比较好,这是动态来调整的。

  • 内存泄漏时有发生,所以我们需要对每一个子进程服务的请求数量做限制.max_request设置就是用来限制内存泄露的。

pm.max_requests = 1000  #每个子进程在处理了1000个请求数量之后就重启
  • php脚本取max_execution_time与request_terminate_timeout最小值作为脚本的超时时间。 这个是用来处理因为PHP执行时间超长而报502错误的解决。

  • 计算合适的进程数(max_children)

    • static : M / (m*1.2)
    • dynamic : [ (N + 20% ),(M/m) ]
    • m :php进程平均内存使用量; M:内存数量;N:cpu数量

实例分析

; Process manager 
pm = static 
pm.max_children = 160 
pm.process_idle_timeout = 15s
pm.max_requests = 1000

配置解析

  • pm = static 静态分配模式 固定数量的子进程
  • pm.max_children = 160 同时最多运行 160 个 PHP-FPM 子进程
  • pm.process_idle_timeout = 15s 当进程空闲超过 15 秒后会被终止
  • pm.max_requests = 1000 每个子进程处理 1000 个请求后会自动重启 (每个进程最大请求数)
  • pm.max_children = 160 理论上这种配置的qps可以支持在160左右

🛠️ 提升性能的实用建议

若当前配置无法满足需求,或想进一步提升性能,可参考以下思路:

  1. 定位性能瓶颈

    • 启用慢日志:在PHP-FPM配置中设置 request_slowlog_timeout 和 slowlog,找出执行慢的脚本。
    • 监控服务器资源:使用 tophtopvmstat 等工具监控CPU、内存、I/O,看瓶颈在哪。
    • OPcache优化:确保启用并正确配置OPcache)。这对ThinkPHP、Laravel等框架性能提升显著。生产环境可考虑设置 opcache.validate_timestamps=0 并配合发布机制更新缓存
  2. 架构与配置优化

    • 考虑冷热池分离:若应用同时有高频短请求(如API)和低频长任务(如报表导出),可考虑配置独立的PHP-FPM进程池(冷热池)分别处理。热池配置为 static 或偏大的 dynamic 模式保证快速响应;冷池配置为 ondemand 或保守的 dynamic 模式。
    • 调整进程管理方式:若流量波动大,可考虑 pm = dynamic 模式,并设置 pm.start_serverspm.min_spare_servers 和 pm.max_spare_servers
    • 后端服务优化:优化数据库查询、使用Redis等缓存高频读写数据。