Nginx 返回 502/504,PHP-FPM 日志出现 max_children reached 或 listen queue 满。
PHP 站点间歇性 502/504,静态资源正常;Nginx error log 出现 connect() to unix:/run/php/php-fpm.sock failed (11: Resource temporarily unavailable) 或 upstream timed out。FPM 日志可能提示 server reached pm.max_children setting。
先看 FPM 日志和进程状态,再看队列与内存预算:
journalctl -u php-fpm --since '30 min ago' --no-pager | tail -100
tail -100 /var/log/php-fpm/error.log
tail -50 /var/log/php-fpm/www-error.log
systemctl status php-fpm
ps -o pid,rss,cmd -C php-fpm
开启 status 页后读取关键字段(listen queue、active processes、max children reached、slow requests):
pm.status_path = /status
curl -s http://127.0.0.1/status?full | sed -n '1,40p'
curl -s http://127.0.0.1/status | grep -E 'active|idle|queue|max children|slow'
再看 socket 队列、系统 backlog 和内存:
ss -lntp | grep -E 'php|9000'
sysctl net.core.somaxconn
smem -t -P php-fpm
grep -E 'failed \(11|upstream timed out|no live upstreams' /var/log/nginx/error.log | tail
listen queue 持续大于 0、max listen queue 很大,说明请求在等待 worker;active processes 长期等于 pm.max_children 则是 worker 被打满。
易误判:max children reached 是累计计数器,历史大于 0 不代表当前过载,必须结合 active processes 和 listen queue 看当下。另一个坑是把各 worker 的 RSS 直接相加来算内存预算 —— opcache 和共享库会被重复计算,应使用 smem 的 PSS 或单 worker 私有内存估算。
active processes 顶到上限。pm.max_children 超过内存预算,多个 pool 叠加后触发 OOM Killer。pm.max_requests=0 从不回收。listen.backlog 或 net.core.somaxconn 太小,Unix socket 接受队列溢出。request_terminate_timeout 与 Nginx fastcgi_read_timeout 不匹配,网关先断或 FPM 先杀。pm 的 spare 参数不合理,频繁 spawn/kill worker,增加延迟。rlimit_files 太小,worker 打开文件/连接失败。request_slowlog_timeout=5s 和 slowlog 抓慢请求栈,先修慢接口再谈扩容。max_children ≈ 可用内存 × 0.8 / 单 worker PSS,并给 opcache 留余量。pm.max_requests=500~1000,让泄漏 worker 定期退出;同时继续定位泄漏。listen.backlog(如 1024)并同步 net.core.somaxconn,再考虑横向扩容。fastcgi_read_timeout 略大于 FPM request_terminate_timeout,避免网关先断开。emergency_restart_threshold、emergency_restart_interval、process_control_timeout 做兜底恢复。phpfpm_active_processes、phpfpm_listen_queue、phpfpm_max_children_reached、phpfpm_slow_requests。pm.max_children?(11: Resource temporarily unavailable) 通常对应哪一层问题?listen queue 持续大于 0、max listen queue 偏高,同时 active processes 接近 pm.max_children。somaxconn 不足,接受队列溢出,而非 worker 崩溃。