===已解决===
这个问题已经解决了。原来是 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
这不是一个答案,而是一个帮助您找到这个问题的一系列步骤。
- 安装 Ganglia: http://ganglia.sourceforge.net/。这是我首选的负载故障排除工具。您一定会喜欢它。
- 看看你是否可以使用负载均衡器将较小比例的流量(例如 5%)发送到新服务器。这有望让你的服务器运行更长时间。
- 在新服务器上运行 top,并通过“P”排序键按 CPU 排序。查看哪个进程占用了大部分周期。
- 仔细检查所有 PHP 绑定到 MySQL 和 Apache 以及库是否安装正确。根据您迄今为止提供的信息,这是我怀疑哪里出了问题的第一点。您手动编译了 PHP 这一事实也引发了潜在的危险信号。仔细检查您的配置选项,确保在 32/64 位更改中预期或要求的内容没有任何变化。
- 启用并查看日志:php error_log 和 apache 错误日志,查看发生了什么。这总是有用的,但您需要在特定环境中将信号与噪音区分开来。
这些步骤中的一个或多个可能有助于查明到底出了什么问题。
答案2
如果您切换到发行版的 php 或 php53 包,是否仍然会出现高 CPU 使用率的情况?
如果您正在使用操作码缓存,禁用它后是否仍会出现高 CPU 使用率?
如果您针对简单的“hello world”PHP脚本而不是实际应用程序运行像apachebench这样的工具,是否仍然会出现高CPU使用率?
您能否逐个禁用 PHP 模块并测试禁用每个模块后是否仍然会出现高 CPU 使用率?
您可以使用 PHP 分析器/调试器来分析应用程序中发生的情况吗?