pm.max_children需按实际内存倒推:先用ps查PHP进程平均RSS(如37.5MB),预留30%–50%系统内存后计算上限并打八折,再同步调优start_servers、min/max_spare_servers,启用status_path与慢日志定位真因。

宝塔 PHP-FPM 频繁挂掉,八成不是配置没保存,而是 pm.max_children 设得既超内存又没兜底——它直接决定最多能 fork 多少个子进程,而每个进程吃多少内存,你得自己量。
怎么算 pm.max_children 才不爆内存
别抄网上“CPU 核数×2”或“设成 100”的模板。真实值取决于单个 PHP Worker 实际 RSS 内存,不是理论值。
- 先查当前活跃进程平均内存:
ps aux --sort=-%mem | grep php-fpm | head -n 5,盯紧RSS列(单位 KB),取中间值(比如 38400 KB ≈ 37.5MB) - 预留 30%–50% 内存给系统、MySQL、宝塔自身;若总内存 2GB,可用约 1.2GB 给 PHP-FPM
- 计算上限:
floor(1200 / 37.5) ≈ 32,再打八折取25作为pm.max_children - 检查
pm.min_spare_servers和pm.max_spare_servers是否 ≤pm.max_children,且pm.min_spare_servers ≥ pm.start_servers × 0.7
改完 pm.max_children 还挂?重点看这三个地方
宝塔点“保存”只是写入模板,不等于生效。常见现象是 php-fpm -t 报错,或 systemctl status php-fpm 显示旧值。
- 确认改的是当前 PHP 版本的主配置文件,路径类似
/www/server/php/80/etc/php-fpm.conf,不是www.conf - 打开
php-fpm.conf,确认末尾有include=/www/server/php/80/etc/php-fpm.d/*.conf,且www.conf里没重复定义pm.*参数(冲突时以最后加载的为准) - 改完必须执行
bt restart php或在宝塔界面点「重载配置」,仅「保存」不 reload,等于白改
为什么调了 pm.max_children 还是 502 或超时
502 不等于进程不够,更可能是慢请求占满池子、Nginx 超时、或后端阻塞导致 worker 卡死。
立即学习“PHP免费学习笔记(深入)”;
- 启用
pm.status_path(宝塔默认关),在www.conf加pm.status_path = /status,然后用curl http://127.0.0.1/status?full查真实active processes是否真打满 - 看慢日志:
/www/wwwlogs/php_slow_*.log(注意按 PHP 版本分目录),重点扫duration> 1s 的script_filename - 同步调大 Nginx 的
fastcgi_read_timeout(默认 60s),否则 PHP 脚本跑 90s,Nginx 先断连,报 502 - 检查数据库连接是否漏
close()、Redis 是否设了timeout、file_get_contents是否带stream_context_create超时
pm = dynamic 下 pm.start_servers 设太低会卡顿
宝塔默认 pm.start_servers = 2 或 5,高并发一来,新请求排队等 fork 进程,延迟直接飙到 2s+。
- 进宝塔「网站」→「PHP 设置」→「性能调整」,看「当前运行中进程数」5 分钟低谷值(比如常在 10–14 之间)
-
pm.start_servers建议设为该区间的下限(如 10),pm.min_spare_servers设为 8–10,避免空闲时过度回收 - 如果站点有定时任务或早高峰突增,
pm.start_servers可比低谷值高 2–3,但别超过pm.max_children × 0.3 - 绝对别用
ondemand模式——冷启动延迟高,WordPress 类站点极易 502
真正难的不是算数字,而是每次调参后盯住 ps aux --sort=-%mem | grep php-fpm 和慢日志,看哪个脚本在悄悄拖垮整个池子。



















