Apache 达到 MaxClients 并锁定服务器

Apache 达到 MaxClients 并锁定服务器

我目前有一台 Apache2 服务器,它运行mpm-preforkmod_phpOpenVZ VPS 上,具有 512M 实际 RAM / 1024M 突发 RAM(无交换)。运行一些测试后,我发现 Apache 获得的最大进程大小为 23M,因此我将其设置MaxClients为 25(23M x 25 = 575 MB,对我来说没问题)。我决定在我的服务器上运行一些负载测试,结果让我感到困惑。

我正在ab我的台式机上请求来自 wordpress 博客的主页。

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

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

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

我的问题是:这是预期的行为吗?为什么 Apache 在达到 时就死机了MaxClients?如果它可以在 24 个连接下工作,那么在 25 个连接下难道不应该工作吗?只是可能需要更多时间来响应每个请求并将其余请求排队?

对我来说,这听起来有点奇怪,任何一个孩子ab只需设置与服务器的并发连接就可以独自杀死一个网络服务器MaxClients

答案1

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

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

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

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

答案2

这里发生的情况是,您有 25 个线程可以接受连接,并且您正在发送 26 个并发请求。最后一个请求位于套接字队列中,具体取决于您的积压大小。

第二个问题是,无论您运行什么都需要 2-3 秒,响应的时间都足够长,25 个并发连接会减慢它的速度。sleep(1) 可能会起作用,但是,当您从 mysql 执行文件锁定或表锁定时,每个并行请求可能都在等待先前完成,直到达到 45 秒超时。

对于加载了 mod_php 和任何模块的 apache 进程来说,23mb 听起来很小,因此,我怀疑您可能会看到这些 apache 进程在应用程序运行时占用更多的内存。您无法真正用 MaxClients 和内存进行数学运算...它会有点接近,但您永远不知道。

www-data  1495  0.1  0.9  56288 19996 ?        S    15:48   0:01 /usr/sbin/apache2 -k start
www-data  1500  0.0  0.5  49684 12436 ?        D    15:48   0:00 /usr/sbin/apache2 -k start

有一台机器,56M 和 49M 进程。

另一台机器:

www-data  7767  0.1  0.1 213732 14840 ?        S    14:55   0:08 /usr/sbin/apache2 -k start
www-data  8020  0.2  0.1 212424 13660 ?        S    14:57   0:08 /usr/sbin/apache2 -k start

另一台机器:

www-data 28509  0.8  0.1 161720 10068 ?        S    14:39   0:43 /usr/sbin/apache2 -k start
www-data 28511  0.8  0.1 161932 10344 ?        S    14:39   0:43 /usr/sbin/apache2 -k start

因此,内存使用在很大程度上取决于任务、加载了哪些模块等等。对于最后两个,我相信我们已经禁用了 pdo 和 pdo_mysql,因为该应用程序不使用它们。

真正的问题是,您正在做什么,这需要 3 秒钟?在当今世界,这已经是一段漫长的时间,并且被视为“阻塞”应用程序。Apache 通常不会死机,但会将这些线程留在积压队列中,直到它可以为它们提供服务或等待的请求超时。我相信您的应用程序可能会导致 Apache 超时。在仅包含 phpinfo(); 的页面上尝试一下,看看结果是否相同。

相关内容