总体判断
在 CentOS 上,PHP-FPM 的内存占用取决于并发连接数、单个子进程的实际内存以及 pm(进程管理方式)等配置。单个 PHP-FPM 子进程在生产环境中常见为 20–30MB,但在某些应用或扩展下可能涨到 30MB 以上;当并发上来或 pm.max_children 设置偏大时,总内存会成倍增加,表现为“占用高”。因此,它并非天生“吃内存”,关键在于进程数量与每个进程的内存基线是否匹配服务器可用内存。
快速自检
- 查看进程数量与占用:
- pstree | grep php-fpm
- ps auxw | head -1; ps auxw | sort -rn -k4 | head -50
- 观察 FPM 日志是否提示进程不足:
- tail -f /var/log/php-fpm/error.log
- 若出现 “server reached pm.max_children setting, consider raising it”,说明并发上来时子进程不够用(也可能意味着需要限流或优化应用)。
- 区分“重启/访问探针后回落”的现象:
- 若访问探针或重启后内存迅速下降,往往指向应用或某些扩展存在内存问题,需要按日志与请求链路定位根因,而非依赖临时释放。
降低内存占用的要点
- 控制并发子进程数量
- 估算公式:MaxChildren ≈ 可用内存 / 单个子进程内存(建议先按 20–30MB/进程 粗估,再压测校准)。
- 小内存机器优先用 pm = dynamic,大内存(如 ≥8GB)可考虑 pm = static 获取更稳定的性能。
- 动态模式常用组合示例:pm.start_servers=5,pm.min_spare_servers=2–5,pm.max_spare_servers=8–12(按并发与内存再细调)。
- 设置进程回收
- 使用 pm.max_requests(如 500)定期回收子进程,缓解第三方扩展潜在内存泄漏带来的驻留增长。
- 优化应用与运行时
- 启用并合理配置 OPcache(如 memory_consumption=64 等),减少重复编译开销,通常能降低总体内存压力与 CPU 占用。
- 排查慢请求与大对象加载:优化 SQL/循环/递归,避免一次性把大文件或大数据集全部载入内存;必要时用生成器与流式处理。
配置示例
- 场景:2GB 内存,Nginx/MySQL 同机,目标并发约 20
- 估算:按 25MB/进程,MaxChildren ≈ 2GB/25MB ≈ 80;为留出系统与其他服务余量,可先设 40–50。
- 建议(动态模式):
- pm = dynamic
- pm.max_children = 45
- pm.start_servers = 5
- pm.min_spare_servers = 3
- pm.max_spare_servers = 10
- pm.max_requests = 500
- 压测后按监控与 FPM 日志微调;若发现频繁达到上限或 502,再评估扩容或优化应用瓶颈。