PHP-FPM 进程池调优实战:pm 参数、慢日志与 502 排查

PHP-FPM 调优封面

这篇指南帮助你调优 PHP-FPM(PHP FastCGI Process Manager)的进程池配置,重点是 pm 参数选择、慢日志启用和 502(Bad Gateway)错误排查。PHP-FPM 配置不当会直接表现为 502 错误或响应缓慢,调优可以从 pm.max_children、pm.start_servers 等核心参数开始。

如果你的 WordPress 或 PHP 应用运行在 数据库优化已经做过的基础上,PHP-FPM 调优可以进一步提升 PHP 层处理能力。Hostease 中文博客的 Nginx 限流配置在前端控制流量,PHP-FPM 在后端处理 PHP 请求,两者配合才能避免过载。

一、pm 模式选择

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

  • static:固定进程数。pm.max_children 启动时就全部启动,适用于流量稳定的场景。
  • dynamic:动态调整。空闲进程超过 pm.max_spare_servers 时回收,少于 pm.min_spare_servers 时创建。
  • ondemand:按需创建。有请求才启动进程,空闲后销毁。适合低流量场景。

大多数生产环境推荐 dynamic 模式,平衡内存占用和响应速度。流量稳定的大站点可以用 static 模式,避免进程动态创建开销。低流量或不常访问的站点用 ondemand 模式节省内存。

# /etc/php-fpm.d/www.conf
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 1000

pm.max_children 设置过大可能导致内存耗尽。每个 PHP-FPM 进程通常占用 30-80MB 内存,8GB 内存服务器最多设置约 100 个进程。pm.max_requests 限制单进程处理的请求数后自动重启,避免内存泄漏累积。

PHP-FPM 进程池工作流程

二、慢日志与监控

启用 PHP-FPM 慢日志可以追踪慢 PHP 请求的原因。

slowlog = /var/log/php-fpm/www-slow.log
request_slowlog_timeout = 5s

request_slowlog_timeout 设 5 秒,超过这个时长的请求会记录到慢日志,包括 PHP 堆栈跟踪。慢日志可以定位慢函数调用、慢数据库查询、慢 API 调用。

监控 PHP-FPM 状态需要启用 status 页面。

pm.status_path = /php-fpm-status
pm.status_listen = 127.0.0.1:9001

访问 http://127.0.0.1:9001/php-fpm-status 可以查看活跃进程数、空闲进程数、队列长度、慢请求数。把这些指标接入监控平台(如 Prometheus),可以提前发现 PHP-FPM 过载的迹象。

三、502 错误排查

502 Bad Gateway 通常表示 PHP-FPM 无法处理请求,原因可能是进程池满、PHP-FPM 崩溃或配置错误。排查时按以下顺序:

  • 检查进程池状态systemctl status php-fpm 查看是否运行。
  • 查看错误日志tail -f /var/log/php-fpm/error.log 找最近错误。
  • 检查进程数ps aux | grep php-fpm | wc -l 看是否达到 max_children。
  • 测试连接curl http://127.0.0.1:9000 确认 PHP-FPM 监听正常。

如果进程数达到 max_children 且仍有大量请求排队,说明需要增加进程数或优化慢请求。如果进程数远低于 max_children 但响应慢,说明瓶颈在 PHP 代码或下游依赖(如数据库)。如果 PHP-FPM 进程频繁重启,可能是内存泄漏或 max_requests 设置过低。

502 排查流程对比

四、与 Nginx 配合优化

PHP-FPM 通常通过 Nginx 反向代理调用。配置 fastcgi(FastCGI,一种通用的 CGI 接口协议)参数影响性能。

fastcgi_pass unix:/run/php-fpm/www.sock;
fastcgi_index index.php;
fastcgi_connect_timeout 60;
fastcgi_read_timeout 300;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_busy_buffers_size 64k;

fastcgi_read_timeout 设 300 秒适合大文件上传或复杂查询。如果接口响应快可以调到 60 秒。fastcgi_buffers 数量根据响应大小调整,单个 PHP 响应超过 256KB 时建议增加到 32 个 buffer。Nginx 配置错误(如 SCRIPT_FILENAME 路径不对)也会导致 502,配置变更后必须验证。

如果你做了 Nginx 限流配置,限流参数和 PHP-FPM 容量需要匹配:限流阈值太高但 PHP-FPM 容量不足,仍会导致请求积压和 502。建议 PHP-FPM max_children 的 80% 作为 Nginx 限流的 burst 值上限。

五、慢请求根因分析

慢日志定位到具体慢函数后,按以下优先级分析:

  1. 数据库查询:用 MySQL 慢查询分析排查是否有无索引查询。
  2. 外部 API 调用:远程接口响应慢会导致 PHP 请求慢,配置超时避免长时间阻塞。
  3. WordPress 插件:每个插件都会增加 PHP 执行时间,停用非必要插件。
  4. PHP 配置:opcache(PHP 字节码缓存)、JIT(Just-In-Time,即时编译)是否启用,会显著影响 PHP 性能。

opcache 是 PHP 7+ 的内置缓存模块,把 PHP 脚本预编译为字节码缓存到共享内存,避免每次请求都重新编译。

opcache.enable=1
opcache.memory_consumption=128
opcache.interned_strings_buffer=8
opcache.max_accelerated_files=10000
opcache.revalidate_freq=2
opcache.fast_shutdown=1

opcache.memory_consumption 默认 64MB,对于中等规模 WordPress 可以调到 128MB。opcache.max_accelerated_files 要大于项目实际 PHP 文件数,建议先 du -sh 统计再调整。

六、监控与告警

长期监控 PHP-FPM 状态,关键指标包括:活跃进程数(应稳定在 max_children 附近)、慢请求数(应该为 0 或极少)、请求排队数(应为 0)。用 Prometheus 抓取 php-fpm-exporter 或 status 页面,设置告警阈值。告警触发时按本节排查顺序定位根因:先看进程数再看慢请求最后查依赖。PHP-FPM 调优不是一次性工作,业务增长后需要定期复核进程池容量。

监控告警的设置要分级别:紧急级别是进程数达到 max_children 且请求排队数大于 0,说明已经过载;警告级别是慢请求数突增,可能是某类请求变慢;提示级别是 max_spare_servers 频繁调整,说明流量波动大。不同级别对应不同的通知策略:紧急告警需要立即响应,警告需要工作时间排查,提示可以在周报中关注。还可以设置恢复告警,进程数回落到正常区间时通知确认问题已解决。

除了 PHP-FPM 自身的指标,还要监控与之相关的上游和下游:上游 Nginx 的 active connections、下游数据库的连接池使用率、上游 PHP 应用的 error log 数量。这些关联监控能帮助快速定位问题:如果是 PHP-FPM 进程数过载但 Nginx 连接数正常,说明 PHP 处理慢;如果是数据库连接耗尽,说明慢请求是数据库引起;如果是 PHP error log 突然增多,说明代码层有异常。结合多维度监控比单维度监控更有效。

对于生产环境,建议建立 PHP-FPM 性能基线。在业务正常时记录典型指标:平均活跃进程数、慢请求率、平均响应时间、最大响应时间、错误率。当监控指标偏离基线时触发告警,比绝对阈值告警更准确。基线要定期更新(每月或每季度),随着业务变化和容量调整更新基线。

总结

PHP-FPM 调优的核心是 pm 参数、慢日志和 502 排查。pm 模式选择和 max_children 设置决定最大并发能力,慢日志定位慢请求根因,502 排查需要按进程状态、错误日志、进程数、连接测试的顺序逐项排查。Nginx fastcgi 配置和 opcache 启用是补充优化。建议在 Hostease 这类 [VPS](https://cn.hostease.com/vps/) 环境部署 PHP-FPM 状态监控,把活跃进程、慢请求、请求排队纳入告警,避免 PHP-FPM 过载成为业务可用性的瓶颈。

发表评论