PHP-FPM并发上不去主因是pm.max_children设置过高导致OOM或过低导致进程不足,需根据单进程内存占用(如40MB/2GB内存→设50)、dynamic模式下配套参数(start_servers=15、min_spare=15、max_spare=40)、pm.max_requests调至5000–10000,并同步调优Nginx worker_connections(建议4096)、fastcgi缓冲区及系统ulimit,最后通过ps、慢日志、ss命令验证效果。
为什么 PHP-FPM 的 pm.max_children 设为 100 后并发仍上不去?
不是数值越大越好。PHP-FPM 子进程会吃内存,pm.max_children 设太高,机器直接 OOM(Out of memory),Nginx 返回 502 Bad Gateway。关键要看单个 PHP 进程平均内存占用——用 ps aux --sort=-%mem | grep php-fpm 查几个 php-fpm: pool www 进程的 %MEM 和 VSZ,再算均值。比如平均占 40MB,服务器有 2GB 可用内存,那 max_children 安全上限 ≈ (2048 MB ÷ 40 MB) ≈ 51,设成 50 更稳妥。
还要注意宝塔面板默认用 pm = dynamic,但它的 pm.start_servers、pm.min_spare_servers、pm.max_spare_servers 若没同步调高,会导致新请求进来时“等不到空闲子进程”,表现为延迟陡增、504 Gateway Timeout。
-
pm.start_servers建议设为max_children × 0.3(如 50 → 15) -
pm.min_spare_servers至少等于start_servers,避免冷启动抖动 -
pm.max_spare_servers设为max_children × 0.8(如 50 → 40),留出缓冲空间
PHP7.3 下 pm.max_requests 设太小反而拖慢高并发
这个参数控制每个子进程处理多少请求后自动重启。设得太小(比如默认 1000),在高并发下子进程频繁退出/重建,CPU 花在 fork 和加载扩展上,吞吐下降。PHP7.3 内存管理已较稳定,建议调到 5000–10000。但要注意:如果代码里有未释放的全局资源(如 PDO 长连接未 close、静态变量累积),增大该值可能引发内存缓慢泄漏——得先用 xdebug 或 memory_get_usage() 日志确认无泄漏再调。
宝塔面板修改位置:网站 > 设置 > PHP > 配置文件,搜索 pm.max_requests 行直接改。改完必须重启 php-fpm(不是重载)才生效。
立即学习“PHP免费学习笔记(深入)”;
Content at Scale
SEO长内容自动化创作平台
下载
别漏掉 Nginx 侧的并发配套限制
只调 PHP-FPM 没用。Nginx 的 worker_processes 和 worker_connections 是前置瓶颈。PHP7.3 + 宝塔常见问题是 Nginx 默认 worker_connections 512,意味着单 worker 最多处理 512 个连接,而一个页面请求可能占多个连接(JS/CSS/图片)。实际并发能力远低于 max_children。
- 确认 CPU 核数:
nproc,然后在/www/server/nginx/conf/nginx.conf里设worker_processes auto - 把
events { worker_connections 4096; }改大(注意系统ulimit -n要 ≥ 8192,否则报错too many open files) - 检查
fastcgi_buffers和fastcgi_buffer_size,高并发下响应体稍大就容易触发upstream sent too big header错误,建议设为fastcgi_buffer_size 128k; fastcgi_buffers 4 256k;
验证是否真起效:看三处实时指标
改完不能只压测首页就收工。要盯住三个地方:
- 用
watch -n 1 'ps aux | grep php-fpm | grep -v grep | wc -l'看实际活跃子进程数,是否能冲到你设的max_children - 查
tail -f /www/wwwlogs/phpfpm_slow.log(需在宝塔 PHP 配置中开启慢日志),出现大量记录说明某段代码阻塞,不是配置问题 - 用
ss -s看tcp连接总数和TIME-WAIT数量,如果TIME-WAIT持续超 2w,得调net.ipv4.tcp_tw_reuse = 1,否则端口耗尽
最易被忽略的是:宝塔的“PHP服务管理”界面点“重启”有时不彻底,建议终端执行 systemctl restart php-fpm-73(或对应版本号)并确认 ps aux | grep fpm 进程时间戳已更新。