我们运营一个中等规模的网站,每天可以获得数十万的综合浏览量.直到上周末,我们在虚拟机上运行的负载通常低于0.2.操作系统是Ubuntu.
在部署最新版本的应用程序时,我们在部署之前也进行了apt-get dist-upgrade.在我们部署之后,我们注意到CPU上的负载急剧上升(有时达到10并且停止响应页面请求).
我们尝试从PHP中倾倒整整一分钟的Xdebug分析数据,但是通过它只显示了一些有点慢的部分,但没有什么可以解释这个巨大的跳跃.
我们现在很确定我们网站的新版本中没有任何内容可以解决问题,但我们无法确定.我们已经回滚了很多变化,但问题仍然存在.
在查看进程时,我们发现单个Apache进程在更长的时间内使用相当多的CPU而不是严格必要的.但是,当在受影响的进程上使用strace时,我们从未看到任何东西
accept(3,
它在接收新连接之前会挂起一段时间,所以我们实际上无法看到导致问题的原因.
堆栈是PHP 5,Apache 2(prefork),MySQL 5.1.大多数东西都通过Memcached运行.我们尝试过APC和eAccelerator.
那么,我们的下一步应该是什么?有没有我们忽略/不了解的分析方法?
答案最终与Apache无关.如上所述,我们在虚拟机上.我们的用户会话非常大(每个活动用户认为500kB),所以我们有很多磁盘IO.磁盘几乎已满,这意味着Ubuntu花了很多时间来处理事物(或者我们认为).没有简单的方法来扩展磁盘(因为它没有为VMWare正确设置).这完全扼杀了性能,而Apache和MySQL偶尔会使用100%的CPU(很短的时间),并且系统在更新CPU使用率时会很慢,因为它似乎停留在那里.
我们最终建立了一个新的VM(这也让我们有机会彻底记录服务器上的所有内容).在新VM上,我们分配了大量磁盘空间,并将会话移动到内存中(使用memcached).我们的负载在非高峰时使用时降至0.2,并且在接近峰值时使用(在2 CPU VM上).将会话移动到memcached会占用大量磁盘IO(我们经常使用大约2MB/s的磁盘IO,这非常糟糕).
结论; 有时你只需要重新开始... :)
从Apache进程看到一个accept()调用并不常见 - 那就是等待新请求的web服务器.
首先,您需要确定负载的参数.就像是
vmstat 1
将告诉你你的系统是什么.查看'swap'和'io'列.如果在'si'和'so'列中看到除"0"以外的任何内容,则系统会因内存不足而进行交换.考虑减少运行Apache子节点的数量,或者在服务器中丢弃更多RAM.
如果RAM不是问题,请查看"cpu"列.您对'us'和'sy'列感兴趣.这些显示了在用户进程或系统中花费的CPU时间百分比.高'us'数字指向Apache或您的脚本 - 或者可能是服务器上的其他内容.
运行
top
将告诉您哪些流程最活跃.
你排除了你的数据库吗?我在生产LAMP堆栈上看到的意外高负载的最常见原因归结为数据库查询.您可能已经使用昂贵的查询部署了新代码; 或者到达数据集中有足够行以导致先前便宜的查询变得昂贵的程度.
在高负荷期间,做
echo "show full processlist" | mysql | grep -v Sleep
查看是否有长时间运行的查询,或同时运行大量相同的查询.其他mysql工具将帮助您优化这些.
您可能会发现为Apache配置和使用mod_status很有用,这将允许您查看每个Apache子服务器所服务的请求以及它所执行的时间.
最后,建立一些长期的统计监测.像zabbix这样的东西很容易配置,并且可以让你随着时间的推移监控资源的使用情况,这样如果事情变得缓慢,你就会有比较的历史基线,以及更好的问题开始时间.