核心是科学配置PHP-FPM进程数与模式:按内存计算pm.max_children(可用内存×0.8÷单进程RSS),选用dynamic模式并合理设置start/min/max_spare_servers,启用pm.max_requests和listen.backlog防老化与堆积,配合Nginx调优及监控验证。

核心是让 PHP-FPM 进程数既够用又不“抢光”内存,同时避免请求排队和 502 错误。卡顿往往不是因为并发太高,而是进程配置和资源分配没对上实际负载。
看准服务器真实内存,算准 pm.max_children
这个值设大了,PHP 进程吃光内存,系统开始 swap 或 kill 进程;设小了,请求排队,Nginx 等不到响应就返回 502 或超时。别凭感觉,按内存算:
- 先用 ps aux --sort=-%mem | head -10 查几个典型 PHP 进程的 RSS(常驻内存),取个中间值,比如平均占 30MB
- 再用 free -h 看可用内存,留出 20% 给系统和其他服务(如 MySQL、Redis)
- 公式:pm.max_children ≈ (可用内存 × 0.8) ÷ 单进程 RSS
例如:8G 内存服务器,可用约 6.4G,单进程 30MB → 6400 ÷ 30 ≈ 213,建议设为 200 左右
选对进程管理模式,别乱用 ondemand
ondemand 模式看似省资源,但每次新请求都要 fork 进程,冷启动延迟高,突发流量下反而更卡。推荐用 dynamic 模式,它能自动伸缩,兼顾弹性与响应速度:
- pm = dynamic
- pm.start_servers 设为 max_children 的 20%~25%,比如 200 就设 40–50
- pm.min_spare_servers 控制最低空闲数,避免频繁创建,建议设为 start_servers 的 0.7 倍左右
- pm.max_spare_servers 别超过 max_children 的 0.8,防止空闲进程过多拖慢系统
加两道“保险”,防进程老化和连接堆积
光调数量不够,还得防长期运行导致的内存泄漏和连接卡死:
立即学习“PHP免费学习笔记(深入)”;
- pm.max_requests = 500:强制每个进程处理完 500 个请求后自动重启,释放可能累积的内存
- listen.backlog = 1024(在 php-fpm pool 配置里):增大等待队列长度,配合 Nginx 的 fastcgi_read_timeout 和 upstream keepalive,减少连接拒绝
- Nginx 端加上 fastcgi_buffering off(对流式响应场景)或启用 fastcgi_cache(对读多写少接口),进一步分流压力
必须配监控,不能只靠猜
调完参数不验证,等于没调。打开 PHP-FPM 的状态页(pm.status_path),用 curl 定期查:
- 关注 active processes 是否长期接近 max_children
- 看 max children reached 计数是否持续增长——涨了说明真不够用
- 结合 slowlog(开启 request_slowlog_timeout = 5s)定位拖慢整体的脚本,比如没加索引的查询或同步 API 调用



















