Apache 占用过多 CPU

Apache 占用过多 CPU

我正在尝试管理 Amazon 上的一个服务器,该网站网络每月的页面浏览量约为 1 亿次。不幸的是,我的 5 名开发人员团队中没有人拥有丰富的服务器管理经验。

现在我们将 MaxClients 设置为 1400。目前我们的流量大约处于平均水平,总共有 1150 个 Apache 进程在运行,每个进程使用大约 2% 的 CPU!在这 1150 个进程中,其中 800 个当前处于休眠状态,但仍在占用 CPU。我相信有办法优化这一点。我有几个想法:

  1. Apache 似乎为每个连接都创建一个新进程。这正常吗?
  2. 有没有办法可以更快地终止休眠进程?
  3. 我们应该打开 KeepAlive 吗?每个页面加载大约 15-20 个中等大小的图形和大量 javascript/css。

以下是我们的 Apache 设置。我们确实计划尽快聘请一名服务器管理员,但在找到人选之前,我真的很希望得到一些建议。

Timeout 25
KeepAlive Off
MaxKeepAliveRequests 200
KeepAliveTimeout 5

<IfModule prefork.c>
StartServers         100
MinSpareServers      20
MaxSpareServers      50
ServerLimit          1400
MaxClients           1400
MaxRequestsPerChild  5000
</IfModule>

<IfModule worker.c>
StartServers         4
MaxClients           400
MinSpareThreads      25
MaxSpareThreads      75
ThreadsPerChild      25
MaxRequestsPerChild  0
</IfModule>

完整顶部输出:

top - 23:44:36 up 1 day,  6:43,  4 users,  load average: 379.14, 379.17, 377.22
Tasks: 1153 total, 379 running, 774 sleeping,   0 stopped,   0 zombie
Cpu(s): 71.9%us, 26.2%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  1.9%si,  0.0%st
Mem:  70343000k total, 23768448k used, 46574552k free,   527376k buffers
Swap:        0k total,        0k used,        0k free, 10054596k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 1756 mysql     20   0 10.2g 1.8g 5256 S 19.8  2.7 904:41.13 mysqld
21515 apache    20   0  396m  18m 4512 R  2.1  0.0   0:34.42 httpd
21524 apache    20   0  396m  18m 4032 R  2.1  0.0   0:32.63 httpd
21544 apache    20   0  394m  16m 4084 R  2.1  0.0   0:36.38 httpd
21643 apache    20   0  396m  18m 4360 R  2.1  0.0   0:34.20 httpd
21817 apache    20   0  396m  17m 4064 R  2.1  0.0   0:38.22 httpd
22134 apache    20   0  395m  17m 4584 R  2.1  0.0   0:35.62 httpd
22211 apache    20   0  397m  18m 4104 R  2.1  0.0   0:29.91 httpd
22267 apache    20   0  396m  18m 4636 R  2.1  0.0   0:35.29 httpd
22334 apache    20   0  397m  18m 4096 R  2.1  0.0   0:34.86 httpd
22549 apache    20   0  395m  17m 4056 R  2.1  0.0   0:31.01 httpd
22612 apache    20   0  397m  19m 4152 R  2.1  0.0   0:34.34 httpd
22721 apache    20   0  396m  18m 4060 R  2.1  0.0   0:32.76 httpd
22932 apache    20   0  396m  17m 4020 R  2.1  0.0   0:37.34 httpd
22933 apache    20   0  396m  18m 4060 R  2.1  0.0   0:34.77 httpd
22949 apache    20   0  396m  18m 4060 R  2.1  0.0   0:34.61 httpd
22956 apache    20   0  402m  24m 4072 R  2.1  0.0   0:41.45 httpd

答案1

在我看来,您使用的是 prefork mpm。此答案的大部分内容都假设了这一点。

Apache 似乎为每个连接都创建一个新进程。这正常吗?

对于 prefork 来说?是的。

有没有办法可以更快地终止休眠进程?

您确定这些进程没有执行任何操作吗?使用 MaxSpareSevers 设置,您最多只能有 50 个空闲进程。启用 mod_status 并设置 ExtendedStatus 应该允许您查看 Apache 记分牌并允许您查看正在发生的事情。

我们应该打开 KeepAlive 吗?每个页面加载大约 15-20 个中等大小的图形和大量 javascript/css。

启用 KeepAlive 是个好主意。它将允许客户端管道化请求,并允许您更有效地重用 Apache 进程。

与大多数调整一样。首先测量以创建基线,然后更改某项内容,然后重新测量以确定更改可能产生的影响。使用(和绘制)mod_status 对此很方便。

您可能能够使用 worker mpm,这往往有助于提高性能。但是,某些库(尤其是某些 PHP 库)无法与 worker mpm 很好地配合使用。YMMV

要确定您正在使用哪个 mpm,请运行:apache2 -V(或 httpd -V,具体取决于发行版)

答案2

关于这个话题有很多书籍,但为了简单起见:

在单独的层中运行数据库

您的数据库工作负载和 Web 服务器工作负载完全不同,并且会以竞争的方式消耗资源。最好将它们分开,这将有助于您在未来进行扩展。

隔离静态和动态内容

考虑运行更快的 Web 服务器(如 nginx)来处理静态内容,彻底抛弃 apache。如果可以,请在任何地方运行 nginx。

KeepAlive 绝对有帮助

你的大量资源因连接的断开和拆除而被耗费。

页面测试

如需更多好的建议,我强烈推荐:http://www.webpagetest.org/。这将向您展示为什么网站需要很长时间才能加载,并提供了许多修复性能的最佳实践技巧:启用 gzip 压缩、最小化 javascript 和 css 等。请阅读。

相关内容