64 位、16 核机器上的 LAMP 堆栈占用了 100% 的 CPU

64 位、16 核机器上的 LAMP 堆栈占用了 100% 的 CPU

===已解决===

这个问题已经解决了。原来是 ImageMagick 在多 CPU 上有问题。将 ImageMagick 编译为使用一个 CPU 解决了这个问题。

================

我添加了一个新的 Web 服务器作为升级,但它在几秒钟内就崩溃了。

旧机器有 8 个 Xeon 核心,频率为 2.33GHz。新机器有 16 个 Xeon 核心,频率为 2.40GHz。内存在新机器上为 8G 和 32G。

另一个主要区别是从 32 位到 64 位的飞跃。

两者的操作系统都是 CentOS 5.6,Apache 也是 2.2.3-45。

PHP 是 5.2.10 并且是手工编译的。除架构位外,配置选项是相同的。

从所有这些信息来看,您可能会认为新机器会发出尖叫声,但当前的机器可以承受负载,偶尔会翻倒。新机器每次都会在不到一分钟的时间内死机。

内存很好,I/O 也不错,但 CPU 却很吃紧。以下是 mpstat 的输出

旧盒子

09:14:18 PM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
09:14:20 PM  all   31.34    0.00    2.62    9.68    0.12    1.00    0.00   55.24  11163.50
09:14:20 PM    0   53.00    0.00    5.50   16.00    0.50    6.50    0.00   18.50  10249.50
09:14:20 PM    1   36.68    0.00    2.51   11.06    0.00    0.00    0.00   49.75    126.00
09:14:20 PM    2   17.41    0.00    1.99    7.96    0.00    0.00    0.00   72.64    125.50
09:14:20 PM    3   41.00    0.00    3.00    9.00    0.00    0.00    0.00   47.00    125.50
09:14:20 PM    4   30.00    0.00    2.00    7.50    0.00    0.50    0.00   60.00    143.00
09:14:20 PM    5   28.50    0.00    2.00   12.00    0.00    0.00    0.00   57.50    142.50
09:14:20 PM    6   22.61    0.00    1.51    7.54    0.00    0.00    0.00   68.34    125.50
09:14:20 PM    7   21.50    0.00    2.50    6.50    0.00    0.00    0.00   69.50    125.50

新盒子

09:13:41 PM  CPU   %user   %nice    %sys %iowait    %irq   %soft  %steal   %idle    intr/s
09:13:43 PM  all   98.69    0.00    0.81    0.00    0.03    0.47    0.00    0.00   4723.50
09:13:43 PM    0  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   1000.50
09:13:43 PM    1  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM    2  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM    3  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM    4   98.01    0.00    1.49    0.00    0.00    0.50    0.00    0.00      0.00
09:13:43 PM    5  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM    6  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM    7   98.51    0.00    1.49    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM    8  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM    9   99.50    0.00    0.50    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM   10  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM   11  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM   12   95.50    0.00    4.00    0.00    0.00    0.50    0.00    0.00     84.50
09:13:43 PM   13  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM   14  100.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00      0.00
09:13:43 PM   15   87.56    0.00    4.98    0.00    0.50    6.97    0.00    0.00    3640.0  

流量通过负载均衡器进入,两者各占一半。我一打开新机器,负载就飙升到 200,我不得不关掉它,因为它停止接受请求。

strace 对 httpd 的解释似乎没有什么帮助,但下面是 strace -c -f -p 的输出

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 73.52    2.763912         419      6594      1663 futex
  8.65    0.325110          55      5869      4099 open
  5.35    0.201250         107      1873       381 stat
  3.12    0.117305          67      1748       165 lstat
  2.30    0.086434        2010        43           wait4
  1.64    0.061543           7      8825       769 read
  1.31    0.049158         125       394           clone
  0.77    0.028874          53       543           chdir
  0.75    0.028356          29       973           munmap
  0.34    0.012783          35       370           times
  0.30    0.011298         257        44           madvise
  0.24    0.008897           7      1312           fstat
  0.22    0.008225           1      9341         2 poll
  0.18    0.006682           2      2777        14 write
  0.14    0.005358           5      1184           mmap
  0.13    0.005020          19       262           set_robust_list
  0.13    0.004990           3      1688        30 writev
  0.13    0.004799           7       671       598 access
  0.08    0.003194           0      6531           recvfrom
  0.06    0.002404           4       673         8 sendto
  0.06    0.002398           4       578           getcwd
  0.06    0.002367           5       491           mprotect
  0.05    0.002013           4       457           brk
  0.05    0.001965           2       883           semop
  0.05    0.001924           3       760           lseek
  0.04    0.001622           2       845           setitimer
  0.04    0.001525           4       412           epoll_wait
  0.04    0.001486           1      2595           close
  0.04    0.001430           3       412           accept
  0.04    0.001429           3       433       231 connect
  0.04    0.001388           1      1185           rt_sigaction
  0.03    0.000999           2       594           rt_sigprocmask
  0.03    0.000963           0      2325           fcntl
  0.02    0.000935           1       690           setsockopt
  0.01    0.000393           1       534           socket
  0.01    0.000380           1       393        12 shutdown
  0.00    0.000158           1       127           setuid
  0.00    0.000156           0       411           getsockname
  0.00    0.000156           2        70        46 unlink
  0.00    0.000080           0       254           epoll_ctl
  0.00    0.000000           0        64           ioctl
  0.00    0.000000           0        38         6 select
  0.00    0.000000           0        10           alarm
  0.00    0.000000           0       230           getsockopt
  0.00    0.000000           0         3           rename
  0.00    0.000000           0        22           getrusage
  0.00    0.000000           0       127           setgid
  0.00    0.000000           0       254           geteuid
  0.00    0.000000           0       127           setgroups
  0.00    0.000000           0       127           epoll_create
------ ----------- ----------- --------- --------- ----------------
100.00    3.759359                 67166      8024 total

========== 编辑/更新 ==========

我发现,当我按照建议将负载均衡器的流量限制为 10% 时,它仍然崩溃了。当我使用 siege 和 400 个连接对其进行测试时,它表现得非常好。负载有所增加,但徘徊在 6 左右并处理了所有请求。

我已禁用访问日志,但我将其启用了一段时间,并告诉负载均衡器再次开始发送流量。我让它运行,直到负载达到 200,大约需要 3 分钟,然后保存了日志。

我解析了用于围攻的请求日志。这将为我提供更准确的基准。

果然,没有实时数据,只有我一个人在访问,我的负载猛增到 200。我开始将文件分成两半,并测试上半部分和下半部分。我会一直这样做,直到找到导致服务器崩溃的特定请求。

到目前为止,它看起来像是大量使用 ImageMagick 的东西,但我已将 10K GET 请求减少到 50 个,并且仍在继续。

答案1

这不是一个答案,而是一个帮助您找到这个问题的一系列步骤。

  1. 安装 Ganglia: http://ganglia.sourceforge.net/。这是我首选的负载故障排除工具。您一定会喜欢它。
  2. 看看你是否可以使用负载均衡器将较小比例的流量(例如 5%)发送到新服务器。这有望让你的服务器运行更长时间。
  3. 在新服务器上运行 top,并通过“P”排序键按 CPU 排序。查看哪个进程占用了大部分周期。
  4. 仔细检查所有 PHP 绑定到 MySQL 和 Apache 以及库是否安装正确。根据您迄今为止提供的信息,这是我怀疑哪里出了问题的第一点。您手动编译了 PHP 这一事实也引发了潜在的危险信号。仔细检查您的配置选项,确保在 32/64 位更改中预期或要求的内容没有任何变化。
  5. 启用并查看日志:php error_log 和 apache 错误日志,查看发生了什么。这总是有用的,但您需要在特定环境中将信号与噪音区分开来。

这些步骤中的一个或多个可能有助于查明到底出了什么问题。

答案2

如果您切换到发行版的 php 或 php53 包,是否仍然会出现高 CPU 使用率的情况?

如果您正在使用操作码缓存,禁用它后是否仍会出现高 CPU 使用率?

如果您针对简单的“hello world”PHP脚本而不是实际应用程序运行像apachebench这样的工具,是否仍然会出现高CPU使用率?

您能否逐个禁用 PHP 模块并测试禁用每个模块后是否仍然会出现高 CPU 使用率?

您可以使用 PHP 分析器/调试器来分析应用程序中发生的情况吗?

相关内容