Wordpress (nginx 缓存 + Apache + fcgid) 占用全部 8 个 CPU

Wordpress (nginx 缓存 + Apache + fcgid) 占用全部 8 个 CPU

我有一个 WordPress 多用户网站,其中所有 CPU 的使用率都超过 90%:

top - 12:02:58 up 55 days,  5:25, 10 users,  load average: 20.51, 15.66, 14.90
Tasks: 294 total,  24 running, 270 sleeping,   0 stopped,   0 zombie
Cpu0  : 87.5%us,  8.0%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  4.5%si,  0.0%st
Cpu1  : 97.9%us,  1.9%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu2  : 96.0%us,  3.5%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.5%si,  0.0%st
Cpu3  : 97.6%us,  2.1%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu4  : 97.1%us,  2.7%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu5  : 97.9%us,  1.9%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Cpu6  : 97.9%us,  1.6%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.5%si,  0.0%st
Cpu7  : 96.0%us,  3.5%sy,  0.0%ni,  0.3%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Mem:  14369424k total, 11903548k used,  2465876k free,   402360k buffers
Swap:  4063200k total,  3594784k used,   468416k free,  1484116k cached

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                              
30658 apache    16   0  274m  97m 6304 R 62.1  0.7   0:12.49 php-cgi
30686 apache    16   0  213m  92m 6040 R 52.2  0.7   0:03.27 php-cgi
30685 apache    15   0  211m  87m 5764 S 50.3  0.6   0:04.50 php-cgi
28217 apache    16   0  529m 405m 6748 S 49.0  2.9   3:54.72 php-cgi
30468 apache    16   0  414m 291m 6452 R 48.5  2.1   0:49.78 php-cgi
29604 apache    15   0  258m 135m 6464 S 47.4  1.0   2:16.22 php-cgi
28308 apache    16   0  584m 408m 6724 R 43.9  2.9   3:43.07 php-cgi
28266 apache    16   0  550m 374m 6728 R 43.7  2.7   3:58.38 php-cgi
29573 apache    16   0  584m 407m 6592 R 36.8  2.9   1:59.88 php-cgi
30470 apache    16   0  219m  95m 6452 S 36.5  0.7   0:39.66 php-cgi
29138 apache    15   0  513m 334m 6528 S 33.6  2.4   2:03.14 php-cgi
30472 apache    17   0  441m 318m 6272 R 31.7  2.3   0:50.45 php-cgi
28283 apache    16   0  414m 291m 6580 R 29.3  2.1   3:53.06 php-cgi
29858 apache    16   0  251m 127m 6628 R 24.8  0.9   1:15.53 php-cgi
28253 apache    18   0  550m 374m 6580 R 24.5  2.7   4:08.05 php-cgi
30666 apache    15   0  217m  94m 5996 R 24.5  0.7   0:04.68 php-cgi
28208 apache    20   0  584m 407m 6436 R 24.2  2.9   4:36.36 php-cgi
29085 apache    25   0  358m 182m 6488 R 22.6  1.3   2:19.76 php-cgi
28258 apache    25   0  530m 407m 6512 R 22.4  2.9   3:58.70 php-cgi
29574 apache    16   0  530m 406m 6540 S 21.6  2.9   2:19.26 php-cgi
28947 apache    16   0  524m 401m 6476 R 14.1  2.9   2:32.33 php-cgi
28238 apache    15   0  488m 312m 6852 S 12.3  2.2   4:24.34 php-cgi
30464 apache    15   0  274m 151m 6176 R 11.2  1.1   0:19.67 php-cgi
28293 apache    16   0  269m 146m 6460 R  9.9  1.0   3:57.17 php-cgi
28205 apache    25   0  530m 407m 6496 R  9.6  2.9   4:05.49 php-cgi
30471 apache    19   0  263m 140m 6440 R  6.9  1.0   0:47.42 php-cgi

输出显示单个进程使用的最大 CPU 量约为 60%,但有时多达 7 个进程使用了​​超过 90% 的 CPU。

该网站的运行方式如下:

  1. nginx 作为反向代理工作,提供其所能提供的每个静态文件并通过 proxy_cache 指令缓存页面。

  2. 当需要 PHP 脚本时,它会委托给 Apache。这些脚本通过 mod_cgi 使用 ExecCGI 选项运行

  3. Apache 和 nginx 都会对每个可读文件进行压缩

  4. 为了避免一直访问 MySQL,我们将 HTML 片段保存在 memcached 中,根据 telnet 连接中的 stats 命令报告,memcached 目前缓存 2 到 4MB 的空间

  5. Redis 数据库中还保存了一些计数器,主要用于计算每个帖子的页面浏览量。

  6. 没有 WP Super Cache(nginx 进行缓存),没有 XCache。

我不知道如何确定每个 php-cgi 进程到底在做什么,以至于需要如此高的 CPU 需求——在我们开始维护之前,该网站已经被几个不同的软件团队大量修改过。

PHP 错误日志主要显示以下错误:

  1. “无法重新声明 FacebookRestClientException 类”
  2. “调用未定义的函数 e_()”
  3. 无效的 SQL 语法,主要在这里:“WHERE post_id = xxxxx AND blog_id = ”
  4. “允许的内存大小 268,435,456 字节已用尽”
  5. “调用未定义方法 Services_JSON::encodeUnsafe()”

这些实际上都不执行任何计算,所以它们不可能是 CPU 问题的根源。

我尝试跟踪系统调用,发现 lstat、read、write 和 access 会产生等待,而不是 CPU 负载,这是问题所在(对吗?)。此外,还有对 poll 和 select 的调用。

有人可以指点我下一步该检查什么吗?

答案1

你的问题在这里:

没有 WP Super Cache(nginx 进行缓存),没有 XCache。

安装APC Zend OPcache 和 W3 Total Cache 并观察 CPU 使用率下降到几乎为零。

仅APC Zend OPcache 就应该能给你一些喘息的空间。

请注意,W3 Total Cache 并不完全支持多站点,因此必须在每个站点上单独配置。可以将其设置为使用您现有的 memcached 进行缓存。

你也可以摆脱 Apache。它对你毫无用处。

(注意:APC 已被弃用,并且在实践中被证明不可靠。我目前建议改用 Zend OPcache。)

答案2

从你看到的其他错误来看,如果有不是一些未经深思熟虑的代码潜伏其中——代码审查将是解决问题的最佳方法。

Cannot redeclare class FacebookRestClientException

我们知道这个类曾是加载成功,因此我首先要找出脚本正在调用哪些外部 API,它们是否失败,以及它们在运行(或运行失败)时占用的时间有多长——对外部 API 的调用(或一系列调用)考虑不周可能是罪魁祸首。

答案3

内存缓存肯定会有所帮助,特别是对于 WordPress 的内部对象缓存。正如 Michael 所说,W3 Total Cache 并不完全支持多站点,而且它相当全面/复杂/繁重,所以我建议使用一种更纯粹、更简单的替代方案,它与 wordpress.com 上的设置非常相似:APC 对象缓存(对于单个服务器来说,它比 memcached 更快)用于对象缓存和批缓存用于全页内存缓存。请注意每个插件的安装说明,它们与标准插件不同。

显然,如果您尚未安装 APC for PHP,则需要安装它并进行适当调整。例如,stat=0 将显著加快速度,但如果您设置了它,则当任何 PHP 文件发生更改时(例如插件和 wordpress 核心升级),您需要重新启动 PHP 进程。确保安装了 apc.php 面板(您可能需要从 APC 源 tarball 中获取它,具体取决于您的操作系统的软件包),它对于调整和调试非常有用。(请记住,将其锁定/密码保护。)

或者,由于你已经安装了 memcached,因此Memcached Redux插件,其功能与 APC 对象缓存相同。这可能是更简单的方法。

由于您已经在使用 nginx 作为基于文件的 proxy_cache,因此您可能无法从 Batcache 中获得大量好处,但如果您有一些空闲的内存,它肯定不会带来坏处,并且可能通过弥合文件缓存和直接命中 Apache 之间的差距来提供帮助,所以值得一试。

看看你的第 3 点。我强烈建议在 Apache 和 PHP 中禁用 gzipping,即禁用 mod_deflate 并zlib.output_compression = Off在 php.ini 中更改。Nginx 是你的前端,所以无论如何都会为你进行压缩,所以没有必要重复执行 - nginx 可能会更快/更有效地完成此操作,并且它将节省你的 Apache/PHP 进程的 CPU。

有多少插件被激活了?它们都是必需的吗?你能逐个禁用它们,看看每个插件有什么不同吗?我见过一些编码糟糕的插件,它们让网站完全瘫痪,所以如果可以的话,请检查一下这些插件。

您提到该网站已被几个不同的软件团队大量修改。是否有任何版本控制,以便您可以查看所做的更改?这些更改是直接针对核心、主题还是插件?如果是针对核心,您是否可以区分出不同之处以获得更好的画面,或者它是否被修改得太多了?如果您能做到的话,继续将更改从核心重构到网站的主题 functions.php 和离散插件中,这可能会让您的生活变得轻松很多。

相关内容