max_children 应按实际内存倒推:先用 ps 查 PHP 进程平均 RSS(如 32MB),预留 30% 系统内存后计算上限(如 4GB 总内存得 70),再设 start_servers 为日常低谷值(如 12),并启用 slowlog 和 status_path 排查真因。

max_children 设多少才不爆内存又不浪费资源
max_children 不是越大越好,它直接决定 PHP-FPM 最多能 fork 出多少个子进程。每个子进程平均吃掉 20–50MB 内存(取决于扩展加载量和脚本复杂度),设成 100 意味着可能占用 2–5GB 物理内存——而你的服务器可能只有 2GB。
更靠谱的做法是按实际内存倒推:
- 查当前 PHP 进程平均内存:用
ps aux --sort=-%mem | grep php-fpm | head -n 5看 RSS 列,取中间值(比如 32MB) - 留出 30% 内存给系统、MySQL、宝塔自身:若总内存 4GB,可用约 2.8GB 给 PHP-FPM
- 计算上限:
floor(2800 / 32) ≈ 87,再打个八折取70作为max_children - 别忘了检查
pm.max_spare_servers和pm.min_spare_servers,它们应分别 ≤max_children且 ≥pm.start_servers
动态模式(dynamic)下 start_servers 怎么设才不卡顿
宝塔默认用 pm = dynamic,但很多人把 pm.start_servers 设成 2 或 5,结果高并发一来,新请求排队等进程启动,延迟飙升到 2s+。
这个值应该反映「日常最低稳定负载」下的活跃进程数:
立即学习“PHP免费学习笔记(深入)”;
- 开宝塔「网站」→「PHP 设置」→「性能调整」,看「当前运行中进程数」的 5 分钟低谷值(比如常在 12–18 之间波动)
-
start_servers建议设为该区间的下限(如 12),min_spare_servers设为 8–10,避免空闲时过度回收 - 如果站点有定时任务或早高峰突增流量,
start_servers可比低谷值高 2–3 个,但别超过max_children * 0.3 - 改完必须重启 PHP-FPM:
bt restart php或在宝塔界面点「重载配置」,仅「保存」不生效
为什么调了 max_children 还是 502 或超时
502 错误或 Nginx 的 upstream timed out 往往不是 max_children 不够,而是其他环节堵住了:
- 检查
pm.status_path是否启用(宝塔默认关),启用后可用curl http://127.0.0.1/status?full查看真实进程状态,确认是否真达到max_children - 看
slowlog:宝塔在/www/wwwlogs/php_slow.log记录 >1 秒的脚本,大量慢请求会占满进程池,此时加max_children只会让内存更快耗尽 - Nginx 的
fastcgi_read_timeout默认 60 秒,若 PHP 脚本真要跑 90 秒,得同步调大,否则 Nginx 主动断连导致 502 - 数据库连接池没配好、Redis 超时、file_get_contents 外部 API 无超时,都会让 PHP 进程卡死,这类问题调
max_children完全无效
宝塔界面改完没生效?重点检查这三处
宝塔的 PHP 配置页面看似直观,但几个关键路径容易被忽略:
- 修改的是哪个 PHP 版本?宝塔可装多个版本(如 7.4/8.0/8.2),必须进对应版本的「设置」页,改错版本等于白改
- 配置文件实际路径是
/www/server/php/{版本号}/etc/php-fpm.d/www.conf,改完后手动grep max_children /www/server/php/80/etc/php-fpm.d/www.conf确认写入成功 - 宝塔有时缓存旧配置,尤其从低版本升级后,建议改完后执行
kill -USR2 `cat /www/server/php/80/var/run/php-fpm.pid`(平滑重启),比「重载配置」更彻底
真正卡住的往往不是参数本身,而是没验证是否落地、没看慢日志、没区分是 CPU 瓶颈还是 I/O 卡死——这些地方比算 max_children 更容易漏掉。



















