Apache 到达 MaxClients 并锁定服务器

Rod*_*iro 9 timeout openvz mpm-prefork apache-2.2

我目前有一个 Apache2 服务器,mpm-preforkmod_php在 OpenVZ VPS 上运行,具有 512M 真实/1024M 可爆内存(无交换)。运行一些测试后,我发现 Apache 获得的最大进程大小是 23M,所以我设置MaxClients为 25(23M x 25 = 575 MB,对我来说还可以)。我决定在我的服务器上运行一些负载测试,结果让我感到困惑。

ab在我的台式机上使用从 wordpress 博客请求主页。

当我运行ab24 个并发连接时,一切似乎都很好。当然,CPU 上升,空闲 RAM 下降,结果是每个请求的响应时间约为 2-3 秒。

但是如果我运行ab25 个并发连接(我的服务器限制),Apache 会在几秒钟后挂起。它开始处理请求,然后停止响应,CPU 回到 100% 空闲并ab超时。Apache 日志说它已达到MaxClients.

发生这种情况时,Apache 将自己锁定在 25 个正在运行的进程中(如果我检查服务器状态,它们都处于“W”状态)并且只有在TimeOut设置后进程开始死亡并且服务器再次开始响应(在我的情况下它已设置到 45)。

我的问题:这是预期的行为吗?为什么 Apache 到达时就死了MaxClients?如果它适用于 24 个连接,它不应该适用于 25 个连接,只是花更多的时间来响应每个请求并将其余的排队?

对我来说,任何一个正在运行的孩子ab都可以通过设置与服务器的并发连接来单独杀死一个网络服务器,这对我来说有点奇怪MaxClients

Rod*_*iro 17

哈!我终于自己发现了问题。它与编程比服务器管理员更相关,但我还是决定把答案放在这里,因为通过搜索谷歌我发现我不是唯一一个有这种问题的人(而且由于 Apache 挂起,第一个猜测是有问题与服务器)。

问题不在于 Apache,而在于我的 Wordpress。更具体地说是我的主题。我正在使用一个名为 Lightworld 的主题,它支持向博客标题添加图像。为此,它使用 PHP 的函数检查图像大小getimagesize()。由于此函数打开另一个到服务器的 http 连接以获取图像,因此每个请求ab都在 PHP 内部创建另一个请求。当我使用所有服务器可用插槽时,这些 PHP 请求被放入队列中,但 Apache 永远无法访问它们,因为它的所有进程都被原始请求锁定,等待插槽完成 PHP 内部请求。

基本上,PHP 将我的服务器置于死锁状态,而 Apache 只会在这些连接超时等待其“子”请求后才开始正常工作。

从我的主题中删除此功能后,现在我可以根据ab需要使用任意数量的并发连接我的服务器,并且 Apache 正在按预期对它们进行排队。