Apache 进程消耗过多 CPU

Apache 进程消耗过多 CPU

我有一个 ubuntu apache/php 服务器,运行 php,每秒点击次数约为 100 次,还有一个 PHP cron 在后台运行。

Apache 进程的 CPU 负载偶尔会很高,无论流量或 cron 活动如何,负载都很高。我觉得它陷入了某种循环或类似情况。

下面您将看到 top 和 strace 信息。

我怎样才能找到错误代码的位置以及导致错误的原因是什么?

top - 14:45:24 up 3 days,  3:38,  1 user,  load average: 5.10, 5.88, 5.85
Tasks: 163 total,   5 running, 158 sleeping,   0 stopped,   0 zombie
Cpu(s): 47.8%us, 18.5%sy,  0.0%ni, 10.2%id,  0.0%wa,  0.0%hi,  1.8%si, 21.6%st
Mem:   7885012k total,  3858484k used,  4026528k free,   177444k buffers
Swap:        0k total,        0k used,        0k free,  1037868k cached
  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
10736 www-data  20   0  769m 559m 478m R   69  7.3  29:08.30 apache2
10844 www-data  20   0  824m 601m 492m S   17  7.8   4:37.90 apache2
 1016 root      20   0  242m  25m 4628 S    6  0.3 162:07.93 scalarizr
 9030 www-data  20   0  879m 619m 492m S    4  8.0   5:06.82 apache2
20216 www-data  20   0  747m 228m 170m S    4  3.0   0:01.94 apache2
10807 www-data  20   0  814m 584m 492m S    3  7.6   4:54.10 apache2
10455 www-data  20   0  831m 574m 492m S    3  7.5   4:32.65 apache2
10495 www-data  20   0  849m 592m 492m S    3  7.7   4:41.10 apache2
10884 www-data  20   0  840m 581m 492m S    3  7.6   4:25.06 apache2




^CProcess 10736 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 74.55    0.148052           1    109755           gettimeofday
 25.36    0.050370           0    164634           clock_gettime
  0.09    0.000178           0     54878           poll
------ ----------- ----------- --------- --------- ----------------
100.00    0.198600                329267           total
root@ec2-67-202-54-36:~# ^C

答案1

我建议启用 Apachemod_status并打开 ExtendedStatus。Slicehost 有一个优秀的文章如何实现这一点(我会使用“elinks”包而不是“lynx”,但这是个人偏好)。当您查看 Apache 服务器状态 URL 时,将会出现 PID、VHost 和 Request 列 - 它们应该有助于精确定位正在调用的 URI,您可以使用它来追溯到正在运行的特定代码。

以下是 Slicehost 文章的定制版本,用于启用 mod_status:

sudo apt-get install elinks
sudo /usr/sbin/a2enmod status
sudo sh -c "echo 'ExtendedStatus On' > /etc/apache2/conf.d/extendedstatus"
sudo vi /etc/apache2/sites-available/server-status

<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from localhost
</Location>

sudo /usr/sbin/a2ensite server-status
sudo apachectl configtest
sudo service apache2 reload

然后查看服务器状态:

elinks -dump -dump-width 256 http://localhost/server-status

答案2

天哪!你的 Apache 似乎占用了太多内存。它到底在运行什么?是否加载了大量 Apache 模块?你是否使用了 mod_security,并且使用了不太占用内存的规则?你的网站是否在运行 Magenta 之类的垃圾程序?此外,某些东西确实让你的 PHP 脚本对当前时间产生了好奇。:D

嗯,对于 PHP 分析,你可以使用调试并分析结果,例如缓存研磨它以易于阅读的图形形式显示结果。

对于实时性能分析,现代 Linux 发行版具有性能命令,就像传统的顶部但您可以深入到单个流程,如果您愿意,您可以在汇编级别查看正在发生的事情。

答案3

例如你应该使用调试器调试,遍历你的程序来找到无限循环。

答案4

您可以使用多种选项来隔离您的问题。

显然,您想检查您的日志并确定是否有任何被报告的问题。

/var/log/access_log 
/var/log/php_error
/var/log/error_log

在 top 运行时按下C还会为你提供有关运行高 CPU 进程的附加数据

正如 dialtOne 所提到的,您可以安装 mod_status 来获取更多详细信息。

我不确定您如何使用 php,但在机器上安装 memcache 和 APC 将节省一些额外的资源。使用 memcache 时,您需要配置代码以首先查看其缓存以进行数据库查找。这可以为访问量大且需要多次重复数据库查找的站点节省大量开销。

调整 php 上的内存设置以及数据库使用的任何设置也有助于控制负载。

它位于您的 php.ini 和数据库配置文件中。

如果您正在使用数据库调用,则可以查找慢速查询。

其他选项是扩展您的子进程和每个子进程的数量,可以在 httpd.conf 中配置。

负载为 5 并不是最糟糕的,这取决于您拥有多少个处理器。我以前见过我们的一些大型 Web 服务器负载非常高,但网站仍然运行良好。这实际上取决于您想花多少精力来调整网站。

祝你好运!

相关内容