直接调 pm.max_children 是内存失控时最该优先调整的参数,需根据单进程平均内存(如40MB)和可用内存(总内存减512MB)计算得出,如2GB服务器应设为38,并同步配置 pm.start_servers=24、pm.min_spare_servers=16、pm.max_spare_servers=32,启用 pm.max_requests_per_child=500 防内存缓慢增长,且必须 restart 而非 reload 才生效。

直接改 pm.max_children 不能根治问题,但它是内存失控时最该优先调的参数——因为多数宕机不是代码泄漏导致的,而是子进程数量超出物理内存承载能力,系统 OOM killer 主动杀掉 MySQL 或 PHP-FPM 自身。
怎么算出合理的 pm.max_children 值
别凭感觉设 50 或 100。先看单个 PHP-FPM 进程实际吃多少内存:
- 用
ps auxw --sort=-%mem | head -n 20查当前占用内存最高的几个php-fpm进程,看 RSS 列(单位 KB),取中间值(比如 35MB–45MB)作为单进程均值 - 用
free -m看可用内存,预留至少 512MB 给系统、MySQL、SSH 等其他服务 - 公式:
pm.max_children = (总内存 - 512) / 单进程平均内存(MB),结果向下取整 - 举例:2GB 内存服务器,实测单进程占 40MB → (2048 - 512) / 40 ≈ 38 → 设为
38比设50更安全
pm.max_children 不是孤立参数,必须同步调配套值
只改 pm.max_children 而不调 pm.start_servers、pm.min_spare_servers,会导致启动瞬间就打满上限,或空闲时仍占大量内存:
-
pm.start_servers应设为pm.max_children的 60%–75%,比如pm.max_children = 38,则pm.start_servers = 24 -
pm.min_spare_servers和pm.max_spare_servers必须在pm.start_servers范围内浮动,推荐设为16和32(即 24±8) - 如果服务器 CPU 核心数 ≤ 2,建议改用
pm = ondemand模式,避免常驻空闲进程
为什么改完还要加 pm.max_requests_per_child
即使代码没明显泄漏,PHP 扩展(如 cURL、GD、OPcache 预热)也会让单个进程内存缓慢增长。不设这个值,跑几天后每个进程可能从 40MB 涨到 120MB,实际内存消耗翻三倍:
- 设
pm.max_requests_per_child = 500是较稳妥的起点(高并发站点可降到 300,低流量可提到 1000) - 该值不是越高越好:超过 1000 后内存增长风险显著上升,且重启开销可控(FPM 子进程重启极快)
- 配合
pm = dynamic时效果最明显;static模式下此参数无效
真正容易被忽略的是:改完配置后必须用 systemctl restart php-fpm,而不是 reload——reload 不会终止已有进程,旧进程继续吃内存,新限制只对后续 fork 生效。观察 24 小时内 free -m 和 ps auxw | grep php-fpm | wc -l 是否稳定,才算真正落地。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











