各位专家,大家好,
在我的专用 CentOS 5.4 服务器上,我为 Apache 配置了大约十几个虚拟主机。我测试了其中几个,每个都在大约一秒钟内加载;相当快。平均负载小于 1。没有问题。我正在运行静态 HTML 站点,一个使用 MySQL 5.0 的 WordPress 博客……这些不是高带宽站点;不会给这台服务器带来压力。
第二天早上,我上班,加载主站点,需要 10 到 20 秒才能加载。我检查了服务器上的平均负载,它徘徊在 3 左右,有时高达 5,曾经看到它达到 8,从未低于 2。此时,我优雅地重新启动 Apache:
# apachectl -k graceful
大约需要半分钟,然后一切又恢复正常。所有虚拟主机加载速度都很快,不到一秒。平均负载很快降至 1 以下。
检查 /server-status 时,没有发生太多事情;检查网络流量(vnstat -l
或vnstat -h
)时,没有使用太多带宽。一天开始时和结束时两者相当。然而,当我在早上检查时,apache 比几乎一整天都慢得多。一夜之间发生了什么,让 apache 速度如此缓慢并消耗了这么多系统资源?
# httpd -V
Server version: Apache/2.2.3
# uname -a
Linux myserver.com 2.6.18-92.el5 #1 SMP Tue Jun 10 18:51:06 EDT 2008 x86_64 x86_64 x86_64 GNU/Linux
# free
total used free shared buffers cached
Mem: 1025576 1017292 8284 0 8208 43160
-/+ buffers/cache: 965924 59652
Swap: 2096472 361012 1735460
我想我可以设置一个 cronjob,每天优雅地弹回 Apache,但这似乎是一个快速而粗略的解决方案。我宁愿找到原因并修复它。
更新时间 2009-10-28 14:38;五分钟内每 10 秒采集一次样本,平均值为:
$ sar -W 10 30 && date
Linux 2.6.18-92.el5 (myserver.com) 10/28/2009
02:32:36 PM pswpin/s pswpout/s
02:32:46 PM 10.31 30.43
02:32:56 PM 2.30 32.93
02:33:06 PM 21.56 0.00
02:33:16 PM 1.80 0.00
02:33:26 PM 5.69 26.67
02:33:36 PM 0.10 0.00
02:33:46 PM 25.70 7.60
02:33:56 PM 10.61 7.11
02:34:06 PM 4.10 2.60
02:34:16 PM 0.70 0.00
02:34:26 PM 0.00 0.00
02:34:36 PM 0.00 0.00
02:34:46 PM 3.80 0.00
02:34:56 PM 0.00 0.00
02:35:06 PM 0.00 11.01
02:35:16 PM 7.70 30.30
02:35:26 PM 20.32 0.00
02:35:36 PM 1.60 0.00
02:35:46 PM 11.60 0.00
02:35:56 PM 2.50 0.00
02:36:06 PM 0.00 0.00
02:36:16 PM 3.60 0.00
02:36:26 PM 0.00 0.00
02:36:36 PM 0.00 0.00
02:36:46 PM 0.00 0.00
02:36:56 PM 445.20 56.60
02:37:06 PM 0.00 0.00
02:37:16 PM 0.00 0.00
02:37:26 PM 0.00 0.00
02:37:36 PM 0.00 0.00
Average: 19.31 6.84
Wed Oct 28 14:37:36 PDT 2009
奇怪的是,今天早上 Apache 并不慢。昨天我对启动的服务器数量、备用服务器数量、最大服务器数量等做了一些调整。让我获取旧值并进行比较...
/etc/httpd/conf/httpd.conf 中的原始值:
StartServers 20
MinSpareServers 20
MaxSpareServers 120
ServerLimit 256
MaxClients 256
MaxRequestsPerChild 4000
从各方面来看,新的价值观似乎都运行良好:
StartServers 30
MinSpareServers 30
MaxSpareServers 40
ServerLimit 50
MaxClients 50
MaxRequestsPerChild 4000
我可能会继续稍微调整这些设置,但它们现在似乎运行良好。
今早再次发出搜救命令:
$ sar -W 10 30 && date
Linux 2.6.18-92.el5 (myserver.com) 10/29/2009
09:31:09 AM pswpin/s pswpout/s
09:31:19 AM 5.80 54.40
09:31:29 AM 62.10 0.00
09:31:39 AM 0.00 0.00
09:31:49 AM 0.00 0.00
09:31:59 AM 0.00 0.00
09:32:09 AM 3.30 0.00
09:32:19 AM 2.70 0.00
09:32:29 AM 0.00 0.00
09:32:39 AM 0.00 0.00
09:32:49 AM 0.00 0.00
09:32:59 AM 3.10 0.00
09:33:09 AM 5.80 0.00
09:33:19 AM 0.00 0.00
09:33:29 AM 0.00 0.00
09:33:39 AM 0.00 0.00
09:33:49 AM 0.00 0.00
09:33:59 AM 0.00 0.00
09:34:09 AM 0.00 0.00
09:34:19 AM 0.00 0.00
09:34:29 AM 0.00 0.00
09:34:39 AM 4.00 0.00
09:34:49 AM 0.10 0.00
09:34:59 AM 0.00 0.00
09:35:09 AM 4.80 0.00
09:35:19 AM 0.00 0.00
09:35:29 AM 291.29 0.00
09:35:39 AM 0.00 0.00
09:35:49 AM 0.80 0.00
09:35:59 AM 0.00 0.00
09:36:09 AM 0.00 0.00
Average: 12.78 1.81
Thu Oct 29 09:36:09 PDT 2009
平均值实际上更低!而且服务器的流量比昨天更多。沃姆布尔,看来你是对的!现在宇宙又恢复正常了。
John Gardeniers,好主意!它有一个-o [filename]
专门用于这个的开关。谢谢你的提示!
Jeremy Visser,dstat
这是一款非常棒的工具!谢谢你的提示!它没有安装,必须安装yum install dstat
。
答案1
根据您的free
输出,我强烈怀疑您的 Apache 进程严重埋没在交换区。 的输出sar -W 1 0
将证实(或反驳)此假设(在机器运行缓慢时运行它)。
如果 Apache 进程实际上并非全部都在处理请求(如 mod_status 所示),则应调整“备用”子进程的数量(使用 MaxSpareServers),以便更快地处理这些子进程(从而不会浪费 RAM)。如果您确实需要运行的子进程数量来处理请求负载,则需要更多 RAM(我会直接再增加 1GB;RAM 很便宜,但诊断时间却不便宜)。
答案2
哪些进程占用了所有内存?在 apache 重新启动之前尝试 iostat/vmstat - 可能是 I/O 问题。
对于趋势监控,我建议使用 munin/colectd(它们甚至有非常有用的 apache(特别是对于你的情况)插件)。