Apache 性能问题,在“总共 1000 个子进程”之后,Apache 不再响应 HTTP 请求。不是 MaxClients 问题?

Apache 性能问题,在“总共 1000 个子进程”之后,Apache 不再响应 HTTP 请求。不是 MaxClients 问题?

希望有人能给我指明正确的方向,因为我花了一周的时间试图找出“问题”在哪里,但却没能成功,尝试过将问题发布到 Apache 用户邮件列表,但也想在这里将其回复。

在 CentOS 5.8 上运行 Apache 2.2.3 mod_php。

同时,每天当流量很大时,我们都会遇到 Apache 不再响应任何 HTTP 请求的问题。

这听起来像是达到标准 MaxClients 的问题,但事实似乎并非如此。

此外,在此期间登录机器时平均负载低于 1,并且仍有足够的可用 RAM。

查看 /var/log/httpd/error_log 我注意到以下模式:

[Mon Apr 30 07:00:34 2012] [info] server seems busy, (you may need to increaseStartServers, or Min/MaxSpareServers), spawning 32 children, there are 0 idle, and 905 total children
[Mon Apr 30 07:00:35 2012] [info] server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers), spawning 32 children, there are 0 idle, and 937 total children
[Mon Apr 30 07:00:36 2012] [info] server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers), spawning 32 children, there are 0 idle, and 969 total children
[Mon Apr 30 07:00:37 2012] [info] server seems busy, (you may need to increase StartServers, or Min/MaxSpareServers), spawning 32 children, there are 35 idle, and 1001 total children

[Mon Apr 30 07:00:42 2012] [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 <br>
[Mon Apr 30 07:00:49 2012] [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 <br>
[Mon Apr 30 07:00:56 2012] [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 <br>
[Mon Apr 30 07:01:03 2012] [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80 <br>

每天几次,就在1000 total childrenApache 停止响应并且必须重新启动才能再次工作之后。

我查看了几周前的 error_log,它是相同的模式,服务器总共达到 1000 个子进程,然后立即吐出 [debug] mpm_common.c(663): (70007)The timeout specified has expired: connect to listener on [::]:80错误消息并停止响应。

但是服务器上的负载很低...即使我尝试请求一个简单的 index.html 文件它也会超时。

以下是配置中的相关部分:

Timeout 45
KeepAlive On
MaxKeepAliveRequests 10000
KeepAliveTimeout 3

<IfModule prefork.c>
StartServers      80
MinSpareServers   50
MaxSpareServers  120
ServerLimit     3500
MaxClients      3500
MaxRequestsPerChild  2000
</IfModule>

有人知道为什么 Apache 在停止处理更多请求之前能够达到的神奇子数是 1000 吗?

或者如何理解这个(70007)The timeout specified has expired: connect to listener on [::]:80信息?

它指的是什么“指定超时”?

我仔细检查了 Max Open Files,之前是 1024,但现在是 16384,仍然是同样的问题。

答案1

虽然可能性不大,但我遇到过类似的问题。我不记得具体是什么错误消息,但问题的原因一直是 PHP 程序存在错误,导致递归请求(即程序请求一个 URL,然后又重新请求同一个 URL 等)。例如,我在ErrorDocument设置中看到过这种情况,其中应该处理错误的文档存在错误或不存在,从而触发了错误。

您可以轻松地在 access.log 中验证这是否是问题所在:您应该会在很短的时间内收到大量来自服务器 IP 地址的请求。这一直有效,直到您达到 MaxClients 设置或系统资源耗尽。唯一的解决办法是修复有问题的 PHP 程序。

答案2

Timeout 45 

我相信它指的是这个超时。可能是某些东西打开了连接,然后什么也没做(即客户端在打开连接后没有发送任何内容,或者您​​的脚本在将数据写入客户端后没有关闭连接),Apache 等待 45 秒后才放弃。然后它关闭连接。您可以降低这个值,这样 Apache 就可以更快地超时无效连接尝试,但更好的解决方案是首先尝试确定为什么会发生这种情况。

http://httpd.apache.org/docs/2.1/mod/core.html#timeout

也许还请查看此页面以了解一般的性能问题?

http://httpd.apache.org/docs/current/misc/perf-tuning.html

答案3

检查 Apache 的 KeepAlive 是否已打开以及 KeepAliveTimeout 的值是多少。它实际上不应超过 3 秒。它将保留分配给客户端的特定进程/线程。

然后在 httpd 的 conf 目录中查找 1000,看看这个数字是否在某处设置。

grep -r '1000' /etc/httpd/conf
grep -r '1000' /etc/httpd/conf.d

除此之外,还可能存在这样的情况:您的 php 代码(错误地)让处理它的每个进程/线程无限期地保持活动状态,而您已经用完了它们。

相关内容