Linux下 PHP-FPM 内存管理优化
一 关键认知与风险
二 快速定位内存瓶颈
free -m、top/htopps -ef | grep "php-fpm" | grep "pool" | wc -lps -ylC php-fpm --sort:rssps --no-headers -o "rss,cmd" -C php-fpm | awk '{ sum+=$1 } END { printf ("%d%s\n", sum/NR/1024,"M") }'pmap $(pgrep php-fpm) | lesspm.status_path = /status,并用 Nginx 暴露;访问 /status?full 可查看 listen queue、idle/active processes、max children reached、slow requests 等关键指标,用于判断进程是否不足或存在慢请求。三 配置优化要点
pm = dynamic:适合内存受限或波动负载,按需增减进程,节约内存。pm = static:适合内存充足且追求稳定低开销的场景,进程常驻,减少调度开销。pm = ondemand:极省内存,但冷启动有延迟,高峰期易出现 504,需谨慎。N ≈ 可用内存MB / (M × 安全系数);建议安全系数取 1.2~1.5,为系统与其他服务预留余量。pm.max_children ≤ N;pm.start_servers 取 N 的 20%~30%;pm.min_spare_servers 与 pm.max_spare_servers 维持适度冗余,常见做法是让 max_spare ≈ 0.6~0.8 × max_children,并确保 max_spare < max_children。N ≈ 1024/(60×1.3) ≈ 13,可设 max_children=12~13,start_servers=3~4,min_spare=3,max_spare=8~10。pm.max_requests:进程处理一定请求后自动重启,用于“兜底”缓解潜在内存泄漏与长期累积膨胀;建议根据业务稳定性与观测结果设置,如 5000~20000,避免过小导致频繁重启、过大失去兜底意义。request_terminate_timeout:请求最大执行时间,超时将被终止;与 php.ini 的 max_execution_time 不冲突,取“先到为准”。长耗时任务应异步化或拆分,而非一味拉高超时。php_admin_value[memory_limit] = 128M(或依据业务调大/调小),防止单请求失控;同时配合 OPcache 减少编译开销、禁用不必要的扩展(如 xdebug 在生产环境),降低单进程内存与 CPU 压力。四 监控与迭代流程
ab/wrk/siege 或业务流量回放,逐步增加并发,观察 内存占用、502/504、响应时延 的变化,验证 max_children 与 max_spare_servers 是否匹配。max_children / spare 阈值,每次变更后至少观察 15~30 分钟;若 listen queue 经常不为 0 或 max children reached > 0,说明进程不足;若 RSS 随运行时间持续单边上涨,优先排查代码/扩展泄漏或缩短 max_requests 兜底周期。