wordpress的404错误太消资源
分类:技术相关日期:2010-07-22作者:邋遢猪仔
一直以来,小张的linux服务器都是我在维护,不过近段时间衡天小张在美国的服务器非常不稳定,原来只是随意的处理了下下,负载降下来了就没再去管,因为最近的事情比较多比较烦,所以也没太多的精力去查是怎么回事。
昨天晚上在San Jose的那台服务器的五分钟负载居然越过了100,把我惹毛了,下定决定要把这个事情解决好,于是查apache请求状态以及分析访问日志,查出的结果很让人吃惊,是wodpress的404页面引起的高负载。
或许,一两个404错误倒没什么,不可能引起这么高的负载。但我们这样打个比方来计算,在安装了wp-super-cache插件的情况下,正常页面访问需要1个CPU单位时间,内存10M,404页面需要消耗的CPU单位时间根据所安装的插件的情况不同,可能需要20个甚至更多,内存30M甚至更多。也就是说wordpress的404消耗的资源是正常访问的20倍以上,从整台服务器来看,高并发wordpress的404可能会导致服务器完全崩溃。所以我得出一个结论,wordpress的404页面成了资源杀手。
现在知道怎么回事了,于是就开始处理,先是查到哪些有很多404的,就把那些帐号给小张,让小张停了。但是停不是办法呀,现在停了,恢复了还是会有404。于是再仔细查,发现很多是mp3的404,那肯定是原来放过mp3文件,而这些文件被百度音乐或是其它的给收录了。现在文件不存在,可能因为各种原因,比如太消耗流量,或者是因为版权的问题,把mp3文件删除了,但那些盗链的信息还在,还是有源源不断的请求,特别是在上网高峰期的时候,请求会更多。所以现在该下手对那些mp3的404下手。前面说了,封帐号不是办法,于是用.htaccess来处理。先找到mp3的404很多的站点,编辑.htaccess,在
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
之后添加一句
RewriteCond %{REQUEST_FILENAME} !\.mp3$
意思就是说,如果请求的文件不是以mp3结尾,则做下面的Rewrite规则。
修改了以后,情况慢慢得到好转了,然后继续从日志里找,找到那些有很多mp3文件请求的404站点,在里面都加了RewriteCond %{REQUEST_FILENAME} !\.mp3$,一切都得到解决了。
在wordpress启用了“永久自定义链接”了以后,所有的当文件不存在请求,都会rewrite到index.php文件,然后所有的都是由index.php来运行,来判断。而wp-super-cache这个插件,貌似不对404页面做缓存,所以这就是问题所在。
另外,在小张的服务器上,偶尔会遇到wordpress因为插件的问题,程序访问自身,出现死循环而大量消耗服务器资源,甚至导致服务器崩溃的情况,为什么会出现这样的情况,目前还没有仔细研究过。
所以建议各位使用wordpress的朋友做这些设置:
1、安装wp-super-cache插件并完全启用它
2、有一个插件叫No Self Pings,这个插件是防止自己ping自己,个人认为对程序访问自身有一定的效果
3、修改.htaccess里wordpress自生的规则,添加 RewriteCond %{REQUEST_FILENAME} !\.(css|js|txt|mp3|zip|png|gif|jpe?g|exe|rmvb|rm|avi)$ 。这个规则的意思是排除css,js,txt,mp3,zip,png,gif,jpg,jpeg,exe,rmvb,rm,avi文件的重写,不管文件是否存在,都直接读,不经过wordpress。下面是一个完整的建议规则。
# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !\.(css|js|txt|mp3|zip|png|gif|jpe?g|exe|rmvb|rm|avi)$
RewriteRule . /index.php [L]
</IfModule># END WordPress
本文原创,转载请注明来自:http://www.newphp.net/contents/147-404-error-of-wordpress-spend-too-much-cpu-time-and-memory
博客搞得不错,欢迎也到我那看看,提提建议。
這個規則轉換Nginx是下面這個嗎?
if (!-f $request_filename){
set $rule_0 1$rule_0;
}
if (!-d $request_filename){
set $rule_0 2$rule_0;
}
if ($request_filename !~ “\.(css|js|txt|mp3|zip|png|gif|jpe?g|exe|rmvb|rm|avi)$”){
set $rule_0 3$rule_0;
}
if ($rule_0 = “321″){
rewrite /. /index.php last;
}
从规则来看,是这样子的,但是我也不能确定倒底是不是可以这样,我对nginx不是很熟悉,特别是nginx的rewrite。
不过可以这样子,直接定义,只要后缀是这些,就不做任何操作,直接输出。
location ~* \.(css|js|txt|mp3|zip|png|gif|jpe?g|exe|rmvb|rm|avi)$ {
log_not_found off;
root /path/to/document;
expires 1y;
}