2008年3月7日星期五

[MediaTemple]虚拟主机内存优化的一点心得

今天下午好像有人对服务器ddos,或者大量灌spam(我不敢说每个人都安装了anti spam插件,即使安装了,"应对"spammer也要消耗服务器资源),http服务器耗尽服务器资源后挂掉,一会儿被watchdog重启,过不了多一会儿再次挂掉。。。以前也尝试过优化apache,不过今天似乎终于摸到了一点儿窍门。

我们合租的MediaTemple服务器cpu负载不高,内存相对紧张:

top - 23:39:45 up 16 days,  7:24,  2 users,  load average: 0.58, 0.50, 0.47 Tasks:  46 total,   1 running,  45 sleeping,   0 stopped,   0 zombie Cpu(s):  9.9% us,  2.5% sy,  0.0% ni, 87.6% id,  0.0% wa,  0.0% hi,  0.0% si Mem:    689496k total,   550892k used,   138604k free,        0k buffers 

所以优化主要针对如何节约内存。主机内存实际是256M,可能是多核的缘故,总显示接近700M内存,不过对应的各个进程占用的内存也相应增加了。MediaTemple的KB中有一篇(dv) HOWTO: Performance tuning (Optimization),先按照这个来优化一下,主要分为三个部分。

优化Apache(httpd)

缩短超时时限:

#Timeout 120 Timeout 30 

调整prefork参数,我调整的结果是:

 #1/1/3 StartServers       1 MinSpareServers    1 MaxSpareServers    3 # 50 ? ServerLimit       20 MaxClients        20 MaxRequestsPerChild  2000  

StartServers是开始的httpd进程数,Min和Max SpareServers是最少和最多空闲进程数,ServerLimit和MaxClients是总进程数限制,这两个参数一般来说是相同的,httpd所消耗的总内存数就和这个相关(实际进程数还会多两个,应该是负责管理子进程的"父进程"),内存不够可以把这两个数值进一步缩小,但这也同时对应着httpd同时处理的并发数。MaxRequestsPerChild是每个进程在处理多少个任务后自杀,根据需要和相关设置还会再启动新的子进程,这种机制有利于释放一些内存碎片。

MaxClients不够会在log产生错误信息,可以用下面的命令查询:

grep -i maxclient /var/log/httpd/error_log 

可以根据情况再调整MaxClients的值,但如果内存就是短缺,又能有什么办法呢?

优化Mysql

设置缓存,在my.cnf的[mysqld]段中增加:

# Cache query-cache-type = 1 query-cache-size = 16M 

虽然会多占用一些内存,但能加快处理的速度,尽快把等待队列"消化"掉,还是有利于加速的。在mysql中可以查询cache使用情况:

mysql> show status like 'Qcache%'; +-------------------------+----------+ | Variable_name           | Value    | +-------------------------+----------+ | Qcache_free_blocks      | 12       | | Qcache_free_memory      | 13028408 | | Qcache_hits             | 35117    | | Qcache_inserts          | 751      | | Qcache_lowmem_prunes    | 0        | | Qcache_not_cached       | 56       | | Qcache_queries_in_cache | 377      | | Qcache_total_blocks     | 872      | +-------------------------+----------+ 8 rows in set (0.00 sec) ...... some times late ...... mysql> show status like 'Qcache%'; +-------------------------+---------+ | Variable_name           | Value   | +-------------------------+---------+ | Qcache_free_blocks      | 88      | | Qcache_free_memory      | 8837920 | | Qcache_hits             | 164437  | | Qcache_inserts          | 3572    | | Qcache_lowmem_prunes    | 0       | | Qcache_not_cached       | 432     | | Qcache_queries_in_cache | 1177    | | Qcache_total_blocks     | 2579    | +-------------------------+---------+ 8 rows in set (0.00 sec) 

调整query-cache-size的值让Qcache_lowmem_prunes保持在0最好,设置太大了也是浪费内存。

关闭不需要的服务

比如named,域名解析使用域名注册商提供的就足够了,关闭spamassassin,邮件服务仅限于对外发送邮件,不接收:

chmod 644 /etc/init.d/psa-spamassassin 

watchdog暂时不建议关闭,人不在的时候它会自动重启服务,还是有一点用处的。

其它优化设置

从其它地方还看到可以开启KeepAlive:

KeepAlive On MaxKeepAliveRequests 100 KeepAliveTimeout 15 

这样每个连接可以发送100次请求,超时时间为15秒。如果KeepAliveTimeout减少一些,MaxKeepAliveRequests还可以设置得更大一点。

还可以启用apache的压缩输出功能:

 #   DeflateCompressionLevel 2     AddOutputFilterByType DEFLATE text/html text/plain text/xml application/x-httpd-php application/x-javascript text/css  

简单观察一下,开启deflate之后,服务器cpu idle值大概会减少15~20%,国外主机数据传输本身就慢,希望这些花销值得。

top - 01:39:03 up 16 days,  9:23,  3 users,  load average: 2.16, 2.09, 1.97 Tasks:  48 total,   1 running,  47 sleeping,   0 stopped,   0 zombie Cpu(s): 24.1% us,  8.4% sy,  0.0% ni, 67.6% id,  0.0% wa,  0.0% hi,  0.0% si Mem:    689496k total,   431452k used,   258044k free,        0k buffers Swap:        0k total,        0k used,        0k free,        0k cached 

结果

现在看一下结果,ps -U apache u能看到一共有20个apache进程在运行,占用内存总量为:

root@fwolf:~# ps -U apache u|awk '{S+=$6} END {print S}' 385396 

随着服务运行,内存使用量还会增加(所以MaxRequestsPerChild别设太大,定期重启一些进程)。再看看那个疑似对我ddos的家伙:

root@fwolf:~# netstat -nap|grep :80|wc -l 513 root@fwolf:~# netstat -nap|grep TIME_WAIT|wc -l 9 root@fwolf:~# netstat -nap|grep 124.115|wc -l 464 root@fwolf:~# netstat -nap|grep 124.115.0|wc -l 376 root@fwolf:~# netstat -nap|grep 124.115.4|wc -l 93 

此时服务器访问稍慢,有时会超时,但起以前动不动内存不足,httpd挂掉要好一些了。查了一下,这个IP地址属于"陕西省西安市 电信",地址总换,但基本都在上面两个网段之内。

再后来,访问量降下来之后,系统就恢复正常了,优化应该还是对服务器速度有一些作用的。

root@fwolf:~# netstat -nap|grep :80|wc -l; netstat -nap|grep TIME_WAIT|wc -l 69 47 

最后贴两张后台流量图表,异常大概开始于18号下午16点,导致18号流量剧增。服务器时间是西8区,所以小时图表中的0点就是16点。按天的那个图表不知为什么出不来,不过注意18号的流量只是前9个小时的就是了。

Free Image Hosting at www.ImageShack.us

Free Image Hosting at www.ImageShack.us

另外,合租的兄弟们,现在新的dv主机默认是PHP 5.2了,咱们啥时候升级呢?

参考

Source: http://www.fwolf.com/blog/post/383