这个坑值得记一笔。晚高峰详情页大量 502,首页是静态缓存所以完全正常,PHP-FPM 日志里全是「pool www seems busy」,pm.max_children 一直停在默认值。
刚开始盯着「慢查询把单个请求拖到十秒以上,进程不释放」,折腾了半个多小时,排掉了。
这类报错背后常见的原因有几处,逐个排除就行。动态页并发上来后子进程被占满,请求排队超时;上游 Nginx 的 fastcgi 超时比 PHP 执行时间短;pm 模式用 static,数量按低峰配置写死。
动手时先看进程池的忙碌和排队情况
curl -s http://127.0.0.1/status?full | grep -E 'active|listen queue'
然后按内存反推合理的子进程数
ps --no-headers -o rss -C php-fpm | awk '{s+=$1} END {print s/1024" MB"}'
调整 pm 模式和上限
pm = dynamic; pm.max_children = 50; pm.max_requests = 500
末了确认详情页恢复且超时消失
for i in $(seq 1 20); do curl -s -o /dev/null -w '%{http_code} ' https://www.example.com/post/$i; done
别只看报错消失,验证要多做一步。详情页批量请求全部返回 200,FPM 状态里排队数为零,502 在日志中不再出现。
这里还有个坑。静态缓存会把故障藏起来,监控要单独探一个不走缓存的动态地址,否则首页永远是绿的。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。
