当前位置:首页>php>PHP-FPM 调优实战:从 100 QPS 到 1000 QPS

PHP-FPM 调优实战:从 100 QPS 到 1000 QPS

  • 2026-10-21 13:27:25
PHP-FPM 调优实战:从 100 QPS 到 1000 QPS

你的 PHP 应用上线后,QPS 上不去?响应时间长?很可能是 PHP-FPM 配置不合理。

今天聊聊 PHP-FPM 的工作原理和调优技巧。


PHP-FPM 是什么

PHP-FPM(FastCGI Process Manager)是 PHP 的进程管理器,负责:

  • 管理 PHP 工作进程池
  • 接收 Web 服务器(Nginx/Apache)转发的请求
  • 分配进程处理请求
  • 回收空闲进程

简单说,Nginx 收到 PHP 请求后,转给 PHP-FPM,PHP-FPM 分配一个子进程执行 PHP 代码,返回结果。


核心配置文件

  • 主配置:/etc/php-fpm.conf 或 /etc/php/8.x/fpm/php-fpm.conf
  • 进程池配置:/etc/php-fpm.d/www.conf 或 /etc/php/8.x/fpm/pool.d/www.conf

进程管理模式

PHP-FPM 有三种进程管理模式:

1. static(静态)

pm = staticpm.max_children = 50

固定数量的子进程,不会动态增减。

  • ✅ 优点:性能稳定,没有进程创建销毁开销
  • ❌ 缺点:内存占用固定,可能浪费资源
  • 📌 适合:流量稳定、内存充足的场景

2. dynamic(动态,默认)

pm = dynamicpm.max_children = 50pm.start_servers = 5pm.min_spare_servers = 5pm.max_spare_servers = 35

根据负载动态调整进程数。

  • start_servers:启动时创建的进程数

  • min_spare_servers:最少空闲进程数

  • max_spare_servers:最多空闲进程数

  • max_children:最大进程数

  • ✅ 优点:按需分配,节省内存

  • ❌ 缺点:高峰期创建进程有开销

  • 📌 适合:流量波动的场景

3. ondemand(按需)

pm = ondemandpm.max_children = 50pm.process_idle_timeout = 10s

没有请求时不创建进程,有请求才创建。

  • ✅ 优点:最省内存
  • ❌ 缺点:首次请求慢(要创建进程)
  • 📌 适合:低流量、资源紧张的场景

关键参数调优

1. max_children 计算

公式:max_children = 可用内存 / 单个进程内存

查看单个 PHP 进程内存:

ps aux | grep php-fpm | awk '{sum+=$6; count++} END {print sum/count/1024 "MB"}'

假设:

  • 服务器 8GB 内存
  • 系统和其他服务占用 2GB
  • 单个 PHP 进程 50MB
max_children = (8 - 2) * 1024 / 50 ≈ 120

保守一点,设置 100。

2. request_terminate_timeout

pm.request_terminate_timeout = 30s

单个请求最大执行时间,超时会被杀掉。防止慢请求占用进程。

3. max_requests

pm.max_requests = 500

每个进程处理多少请求后重启。防止内存泄漏。

  • 设置太小:频繁重启,性能下降
  • 设置太大:可能内存泄漏
  • 建议:500-1000

4. 慢日志

slowlog = /var/log/php-fpm/slow.logrequest_slowlog_timeout = 3s

超过 3 秒的请求会记录到慢日志,方便排查性能问题。


完整配置示例

8GB 内存服务器,中等流量:

[www]user = www-datagroup = www-datalisten = /run/php/php8.2-fpm.socklisten.owner = www-datalisten.group = www-datalisten.mode = 0660; 进程管理pm = dynamicpm.max_children = 100pm.start_servers = 20pm.min_spare_servers = 10pm.max_spare_servers = 50pm.max_requests = 500; 超时设置request_terminate_timeout = 30srequest_slowlog_timeout = 3sslowlog = /var/log/php-fpm/slow.log; 状态页pm.status_path = /fpm-statusping.path = /fpm-pingping.response = pong

高流量场景(16GB 内存):

pm = staticpm.max_children = 200pm.max_requests = 1000

监控 PHP-FPM 状态

开启状态页后,配置 Nginx:

location /fpm-status {    fastcgi_pass unix:/run/php/php8.2-fpm.sock;    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;    include fastcgi_params;    allow 127.0.0.1;    deny all;}

访问 /fpm-status?full 查看详细状态:

pool:                 wwwprocess manager:      dynamicstart time:           01/Jan/2024:00:00:00start since:          86400accepted conn:        123456listen queue:         0max listen queue:     10listen queue len:     128idle processes:       20active processes:     5total processes:      25max active processes: 50max children reached: 0

关键指标:

指标
说明
关注点
listen queue
等待队列
持续大于 0 说明进程不够
max children reached
达到最大进程数的次数
大于 0 要增加 max_children
active processes
活跃进程数
监控负载
idle processes
空闲进程数
资源利用率

Nginx 配置优化

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;    # 超时设置    fastcgi_connect_timeout 60s;    fastcgi_send_timeout 60s;    fastcgi_read_timeout 60s;    # 缓冲设置    fastcgi_buffer_size 64k;    fastcgi_buffers 4 64k;    fastcgi_busy_buffers_size 128k;}

常见问题排查

1. 502 Bad Gateway

原因:PHP-FPM 进程不够或挂了

检查:

  • 查看 PHP-FPM 错误日志
  • 检查 max_children 是否太小
  • 检查是否有进程被 OOM 杀掉

2. 504 Gateway Timeout

原因:PHP 执行超时

检查:

  • 查看慢日志
  • 检查 request_terminate_timeout
  • 检查 Nginx 的 fastcgi_read_timeout

3. 内存不足

原因:max_children 设置过大

解决:

  • 减少 max_children
  • 优化代码减少内存使用
  • 加内存

性能测试

用 ab 或 wrk 测试:

# ab 测试ab -n 10000 -c 100 http://localhost/api/test# wrk 测试wrk -t4 -c100 -d30s http://localhost/api/test

调整参数后对比 QPS 和响应时间。


总结

PHP-FPM 调优要点:

  1. ✅ 根据内存计算 max_children
  2. ✅ 流量稳定用 static,波动用 dynamic
  3. ✅ 开启慢日志排查性能问题
  4. ✅ 监控状态页,关注 listen queue 和 max children reached
  5. ✅ 配合 Nginx 超时和缓冲设置

调优是个持续过程,要根据实际监控数据不断调整。

下一篇进入面向对象进阶,聊聊 Trait 的正确用法。

最新文章

随机文章