CentOS 7.9 上 php-fpm 7.3,站点日志里不停出现 WARNING: [pool www] server reached pm.max_children setting (20), consider raising it,接口 P99 从 300ms 涨到 4 秒,加进程后过几天又出现同样的告警。

一开始怀疑是「静态资源请求也走 PHP,白白消耗进程」,查了一圈,方向不对。

原因不止一个,得分开看。有慢 SQL 或外部接口把进程占住,加进程只是把队列往后挪。少数情况下是pm.max_children 到了但 pm.max_requests 设成 0,进程永不回收。

不容易想到的是,后端 Redis 连接超时,每个请求都卡在等连接上。

上来先看进程都在忙什么

ps -o pid,etime,cmd -C php-fpm | sort -k2 -r | head -10

接着打开慢日志定位耗时长的脚本

grep -nE 'request_slowlog_timeout|slowlog' /etc/php-fpm.d/www.conf

随后把静态请求交给 nginx 不落到 PHP

grep -n -A10 'location ~' /etc/nginx/conf.d/site.conf

末了按内存上限调整子进程并设置回收

sed -i 's/^pm.max_requests.*/pm.max_requests = 500/' /etc/php-fpm.d/www.conf && systemctl reload php-fpm

我习惯把每一步的执行时间和结果记在一边,后面复盘省事。

恢复的判定其实很直接。seems busy 的告警在一小时内不再出现,接口 P99 回到 500ms 以内,php-fpm 的进程数稳定在 15 左右。

提醒一点。告警只是结果,真正要治的是慢请求;每次只调一档并记录改前改后的 P99,才知道加的进程有没有用。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。

作者 9823189