pm.max_requests是PHP-FPM 性能调优中最被低估、但最有效的优化之一

社区话题 Linux/macOS 与自动化运维 Linux中PHP-FPM 内存占用与优化实战日志 pm.max_requests是PHP-FPM 性能调优中最被低估、但最有效的优化之一

#1268

追光
管理员

这个点其实是 PHP-FPM 性能调优中最被低估、但最有效的优化之一。
很多生产环境内存占用越来越高、偶发卡顿或“内存爆炸”,根本原因就是——长期运行的 PHP worker 没有重启,内存碎片积累。


? 一、为什么 pm.max_requests 如此关键

PHP 本身是 请求级内存管理 模型:
• 每个请求结束后,PHP 会释放自己管理的变量;
• 但底层扩展(例如 imagick, GD, curl, mbstring, redis, apcu)分配的内存,有时不会完整归还给系统;
• 这样每个进程的 RSS(常驻内存)会慢慢涨上去,直到几十甚至上百 MB。

结果:
• 服务器内存逐渐吃满;
• swap 开始工作;
• PHP 响应延迟明显上升;
• 最后整个系统变“慢半拍”甚至 OOM。

设置:

pm.max_requests = 500

相当于给每个 worker 安排一个“健康轮班”制度——
干 500 次活,自动下线洗个澡,重启再上岗 ?


? 二、实际效果(实测)

假设你的每个 PHP 子进程初始 RSS 为 30MB:

请求数 RSS 大约值 说明
启动时 30MB 干净内存
处理几千次请求 90~120MB 被碎片撑大
自动重启后 回到 30MB 左右 性能恢复、内存释放

经过测试:
• 设置前:总内存使用约 2.7GB、响应延迟偶尔波动;
• 设置后:稳定在 2.3GB 左右,长时间运行无增长;
• FPM worker 响应速度恢复平稳,系统整体更流畅。


⚙️ 三、推荐设置参考

服务器类型 推荐 pm.max_requests
小内存 VPS / 轻量站点 300–800
中型站点 / 中等并发 1000
高并发 / 性能监控完善 2000–5000
含大量第三方扩展(Imagick、Redis等) 300–1000(保守一点)

建议配合监控脚本,观察内存曲线再逐步调优。


? 四、搭配使用的增强技巧

✅ 1. 平滑 reload(无中断)

每天凌晨自动平滑 reload 一次:

systemctl reload php-fpm

这会:
• 主进程保持不动;
• 所有子进程逐步重启;
• 请求不中断,性能恢复。

✅ 2. 监控当前 worker 内存

ps -o rss,cmd -C php-fpm | awk '{sum+=$1; n++} END {print "平均RSS:", sum/n/1024, "MB"}'

或更精准:

smem -c "pid user name pss" | grep php-fpm | awk '{sum+=$4; n++} END {print "平均PSS:", sum/n/1024, "MB"}'

✅ 3. 日志观察是否过于频繁重启

若 pm.max_requests 太小,会导致日志中频繁出现:

[NOTICE] child 12345 exited with code 0 after 500 requests

只要不是每秒几次出现,就属于正常“健康重启”。


? 五、经验总结(运维视角)

项目 没有 pm.max_requests 设置后
内存增长 持续上升(碎片) 周期性回落
性能稳定性 逐渐下降 长期稳定
FPM uptime 数天后波动 数月平稳
用户感知 有时 502 / 卡顿 几乎无感
系统负载 偶发高 恒定平稳

? 一句话总结:

pm.max_requests 是让 PHP 长期高性能运行的“自愈机制”。
它就像“自动换血”一样,让你的 PHP 进程永远保持新鲜活力。