PHP-FPM 内存与进程模型优化(OOM 排查)

解释 PHP-FPM 的动态进程模型与内存占用关系,讲解 pm.max_children 的计算方法、OOM Killer 的触发原理与排查步骤,并给出适配小内存服务器的参数建议。

PHP-FPM 进程模型

PHP-FPM 用多个 worker 进程处理请求,常用三种 pm 模式:dynamic(固定范围内的动态进程)、ondemand(按需启动)、static(固定数量)。每个 worker 都是独立进程,会各自加载 PHP 与扩展,单进程内存通常在 20-60MB 之间,站点插件越多、扩展越重,占用越高。总内存 ≈ worker 数量 × 单进程内存,这就是调参的核心公式。

max_children 怎么算

先测单个 worker 的实际内存(可通过 ps 或 /proc 汇总估算),再用「服务器可用内存 ÷ 单进程内存」得到上限,并留出 30% 余量给 MySQL、系统缓存与其他服务。2GB 内存的小机器,如果 MySQL 与站点同机,max_children 往往只能设到 10-20;盲目调到 50 会直接触发 OOM。有 MySQL 独立部署或对象缓存占内存较大时,要相应调低。

OOM Killer 现象

当系统内存耗尽,内核的 OOM Killer 会挑内存占用高的进程直接杀掉,现象通常是 PHP-FPM 或 MySQL 突然消失、站点 502/504。确认方式:dmesg | grep -i “killed process” 或 journalctl -k 查看内核日志,若出现 Killed process 即可确认。此时不能只重启服务了事,必须找到内存持续增长的来源。

排查内存持续增长

  1. 观察 PHP-FPM 总内存随时间的变化曲线
  2. 若单个 worker 内存持续上涨,多半是某个扩展或代码存在泄漏
  3. 开启 slowlog 查看执行超过阈值的脚本,定位异常长任务
  4. 检查是否有大数组处理、一次性读入大文件、无 unset 的循环
  5. 确认 OPcache 已启用,避免重复编译 PHP 代码

参数建议

  • 内存紧张:pm=ondemand,减少空闲时的常驻进程
  • 流量稳定:pm=dynamic,设置合理 min/max/start 子进程数
  • 高内存机器:pm=static + 足够 max_children,省去动态调度开销
  • request_terminate_timeout 设置上限,杀掉卡死请求
  • slowlog 必开,否则长脚本无从发现

别忽略的两点

一是 OPcache 与 APCu 能显著降低重复开销,确认 phpinfo 中已启用且内存配额合理。二是避免把 MySQL 的 buffer pool 设得过大与 PHP 抢内存,同机部署时两者要一起规划。改动参数后用压测验证:既要看响应时间,也要盯住内存曲线是否平稳——只有压测通过的配置才值得上线。

Previous Article

crontab 定时任务实战与排错

Next Article

Nginx access.log 与 error.log 定位网站问题

Write a Comment

Leave a Comment

Your email address will not be published. Required fields are marked *