记录一下那天晚上的排查过程。CentOS 7.9 上跑 Apache 2.4 的 prefork 模式,业务侧请求普遍卡到六十秒才超时,error_log 每几分钟刷一条 server reached MaxRequestWorkers setting,server-status 里 BusyWorkers 一直等于上限。

刚开始盯着「KeepAlive 开着而 KeepAliveTimeout 是 5 秒,一个空闲连接也把进程占住」,折腾了半个多小时,排掉了。

这类报错背后常见的原因有几处,逐个排除就行。prefork 每个请求占一个进程,进程数到顶之后新连接只能排在监听队列里等。少数情况下是上游接口变慢,进程被长时间占着不释放,池子很快见底。

还有一种情况,MaxRequestWorkers 受 ServerLimit 限制,只调前者实际不生效。

先确认现在是哪种多路复用模型

httpd -M | grep -E 'prefork|worker|event'

再往下看忙碌与空闲进程的实时比例

curl -s 'http://127.0.0.1/server-status?auto' | grep -E 'BusyWorkers|IdleWorkers|Scoreboard'

然后把进程上限与 ServerLimit 一起放开

sed -i 's/^MaxRequestWorkers.*/MaxRequestWorkers 512/; s/^ServerLimit.*/ServerLimit 512/' /etc/httpd/conf.modules.d/00-mpm.conf && systemctl reload httpd

回头确认报错是否还在刷

tail -200 /var/log/httpd/error_log | grep -c MaxRequestWorkers

别只看报错消失,验证要多做一步。BusyWorkers 稳定在两百以下且 IdleWorkers 始终大于五十,error_log 不再新增 MaxRequestWorkers,接口超时率回到千分之一以内。

补一句。加进程数是在加内存,先算清单进程的常驻占用;event 模式比 prefork 省得多,能换就换。这类问题最好一次改到位,反复小改反而容易把原因搅混。

作者 9823189