之前用C写的一个小巧的Home Server已经伴我数载,一直很稳定的为我的网站提供服务,而且内存只有10MB左右,却可以支持100多个并发请求。更多的并发请求需要增加额外一些内存。因为对wordpress支持最好的服务器程序就是apache2,而且burst.net最近老是给我的服务器重启,Home Server不像apache2那样作成服务会随机启动,所以导致网站无法访问,很不爽。
前些天高高兴兴地换上了Apache2,为了适应OpenVZ的小内存VPS,我已经把并发数设置的相当小了。MaxClients只有50而已。然而,悲剧却发生了,我突然无法连接我的VPS的SSH服务了,提示如下。
root@xiaoxia-pc:~# ssh xiaoxia.org
ssh_exchange_identification: Connection closed by remote host
奇怪了,我以为是密钥的问题。所以我登录了vePortal面板进行管理,发现vePortal也死掉了,控制台无法使用,进程也无法查看。但是奇怪的是,网站却可以正常打开,FTP也能使用,我用python搭建的实验室lab.xiaoxia.org也能正常运行,但是在使用http://lab.xiaoxia.org/server/request/ 页面上的服务执行命令时,失败了。原因如下:
500 Internal Error
Traceback (most recent call last):
File “WebGateway.py”, line 138, in getService
if not self.getController():
File “WebGateway.py”, line 113, in getController
method(*params)
File “controller/server.py”, line 20, in request
buf = self.process(path)
File “controller/server.py”, line 15, in process
return os.popen(cmd, “r”).read()
OSError: [Errno 12] Cannot allocate memory
我想应该是无法创建进程引起的吧,应该是服务提供商的问题。
过了一段时间,果然我又能重新登录SSH服务,但是发现apache异常退出了。我在猜测可能是它占用了太多的内存,出错了。
我开始想到的解决方法是,去掉默认的prefork工作模式,改为worker或者event。换了之后,我发现问题依旧,而且一旦出现内存用尽时,想进行什么操作都无用。这是OpenVZ的VPS最令人头痛的问题了吧,它的限制的内存是虚拟内存占用,而不是实际物理内存的占用。这跟XEN的VPS有本质的区别。但是相同价位的XEN的VPS配置又太低了,才128M的内存,更加不能做站点服务了。
今天无奈之下,就把apache2的最大连接数设为了5,我想这样不会出现内存用尽的问题了吧,算它一个进程使用50MB,50*5 = 250MB也不多,我可能还有200MB剩余呢。结果,新问题又来了。一段时间之后,apache2好像死掉了,访问网站停留在无限的等待中,普通的静态页面也不给我返回任何数据,跟死锁了一样,但是prefork模式是无锁的,无锁也死掉了,不清楚什么原因了。
查一下网络状态如下:
root@244754:~# netstat -ntp Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 184.22.224.212:80 113.105.195.234:7976 SYN_RECV - tcp 0 0 184.22.224.212:80 27.156.69.188:59759 SYN_RECV - tcp 0 0 184.22.224.212:80 125.37.124.2:50740 SYN_RECV - tcp 0 0 184.22.224.212:80 66.249.71.163:54024 SYN_RECV - tcp 0 0 184.22.224.212:80 221.172.103.201:3887 SYN_RECV - tcp 0 0 184.22.224.212:80 27.156.69.188:59668 SYN_RECV - tcp 0 0 184.22.224.212:80 112.96.130.11:1630 SYN_RECV - tcp 0 0 184.22.224.212:80 112.96.130.11:1634 SYN_RECV - tcp 0 0 184.22.224.212:80 123.125.71.98:5598 SYN_RECV - tcp 0 0 184.22.224.212:80 113.141.158.255:1393 SYN_RECV - tcp 0 0 184.22.224.212:80 112.96.130.11:1635 SYN_RECV - tcp 0 0 184.22.224.212:80 124.115.0.24:57274 SYN_RECV - tcp 0 0 184.22.224.212:80 112.96.130.11:1636 SYN_RECV - tcp 0 0 184.22.224.212:80 223.167.161.208:50234 SYN_RECV - tcp 0 0 184.22.224.212:80 112.96.130.11:1623 SYN_RECV - tcp 0 0 184.22.224.212:80 218.59.63.57:2061 SYN_RECV - tcp 267 0 184.22.224.212:80 123.125.71.35:9661 CLOSE_WAIT - tcp 401 0 184.22.224.212:80 58.60.36.30:31649 CLOSE_WAIT - tcp 0 11680 184.22.224.212:80 123.125.71.107:8435 CLOSE_WAIT 32006/apache2 tcp 267 0 184.22.224.212:80 123.125.71.103:44783 CLOSE_WAIT - tcp 282 0 184.22.224.212:80 123.125.71.111:58854 CLOSE_WAIT - tcp 178 0 184.22.224.212:80 184.22.224.212:34649 CLOSE_WAIT - tcp 437 0 184.22.224.212:80 125.37.124.2:50895 ESTABLISHED - tcp 270 0 184.22.224.212:80 124.115.0.22:33928 CLOSE_WAIT - tcp 0 11680 184.22.224.212:80 123.125.71.85:54145 CLOSE_WAIT 30177/apache2 tcp 52 0 184.22.224.212:80 184.22.224.212:34867 CLOSE_WAIT - tcp 178 0 184.22.224.212:80 184.22.224.212:36640 CLOSE_WAIT - tcp 178 0 184.22.224.212:80 184.22.224.212:58669 CLOSE_WAIT - tcp 242 0 184.22.224.212:80 123.126.50.78:40404 CLOSE_WAIT - tcp 198 0 184.22.224.212:80 101.226.33.171:44614 CLOSE_WAIT - tcp 267 0 184.22.224.212:80 123.125.71.101:1912 CLOSE_WAIT - tcp 242 0 184.22.224.212:80 123.126.50.78:33343 CLOSE_WAIT - tcp 490 0 184.22.224.212:80 58.60.36.30:31550 CLOSE_WAIT - tcp 217 0 184.22.224.212:80 114.80.93.57:54796 CLOSE_WAIT - tcp 0 10020 184.22.224.212:80 58.60.36.30:31549 LAST_ACK - tcp 235 0 184.22.224.212:80 123.125.71.13:42558 CLOSE_WAIT - tcp 184 0 184.22.224.212:80 184.22.224.212:37079 CLOSE_WAIT - tcp 0 0 184.22.224.212:80 184.22.224.212:60631 ESTABLISHED - tcp 0 0 184.22.224.212:34867 184.22.224.212:80 FIN_WAIT2 - tcp 238 0 184.22.224.212:80 72.14.199.105:65465 CLOSE_WAIT - tcp 178 0 184.22.224.212:80 184.22.224.212:53197 CLOSE_WAIT - tcp 267 0 184.22.224.212:80 123.125.71.53:42012 CLOSE_WAIT - tcp 434 0 184.22.224.212:80 211.147.4.6:55549 CLOSE_WAIT - tcp 378 0 184.22.224.212:80 120.32.188.252:56564 ESTABLISHED - tcp 340 0 184.22.224.212:80 72.14.199.119:53982 CLOSE_WAIT - tcp 184 0 184.22.224.212:80 184.22.224.212:60606 CLOSE_WAIT - tcp 309 0 184.22.224.212:80 123.125.71.107:8492 CLOSE_WAIT - tcp 309 0 184.22.224.212:80 123.125.71.31:63314 CLOSE_WAIT - tcp 405 0 184.22.224.212:80 58.60.36.30:31811 CLOSE_WAIT - tcp 242 0 184.22.224.212:80 123.126.50.78:35139 CLOSE_WAIT - tcp 242 0 184.22.224.212:80 123.126.50.78:50240 CLOSE_WAIT - tcp 267 0 184.22.224.212:80 123.125.71.25:51314 CLOSE_WAIT - tcp 271 0 184.22.224.212:80 123.125.71.42:35513 CLOSE_WAIT - tcp 282 0 184.22.224.212:80 123.125.71.20:6027 CLOSE_WAIT - tcp 218 0 184.22.224.212:80 124.115.0.19:56002 CLOSE_WAIT - tcp 0 11680 184.22.224.212:80 123.125.71.98:65517 CLOSE_WAIT 30144/apache2 tcp 1 0 184.22.224.212:80 112.96.130.11:1628 CLOSE_WAIT - tcp 0 21600 184.22.224.212:80 120.32.188.161:56437 ESTABLISHED 31999/apache2 tcp 511 0 184.22.224.212:80 119.4.46.213:35722 CLOSE_WAIT - tcp 282 0 184.22.224.212:80 123.125.71.110:63433 CLOSE_WAIT - tcp 267 0 184.22.224.212:80 123.125.71.108:16581 CLOSE_WAIT - tcp 505 0 184.22.224.212:80 221.233.39.110:3138 ESTABLISHED - tcp 301 0 184.22.224.212:80 113.219.105.246:2883 CLOSE_WAIT - tcp 498 0 184.22.224.212:80 113.105.195.234:6984 CLOSE_WAIT - tcp 239 0 184.22.224.212:80 72.14.199.118:61048 CLOSE_WAIT - tcp 0 0 184.22.224.212:22 112.96.130.11:3893 TIME_WAIT - tcp 207 0 184.22.224.212:80 124.115.0.171:49164 CLOSE_WAIT - tcp 286 0 184.22.224.212:80 119.137.117.182:2705 CLOSE_WAIT - tcp 267 0 184.22.224.212:80 123.125.71.88:30288 CLOSE_WAIT - tcp 0 11680 184.22.224.212:80 123.125.71.42:35096 CLOSE_WAIT 30140/apache2 tcp 281 0 184.22.224.212:80 123.125.71.96:50769 ESTABLISHED - tcp 179 0 184.22.224.212:80 123.125.67.152:5469 CLOSE_WAIT - tcp 282 0 184.22.224.212:80 123.125.71.92:48498 CLOSE_WAIT - tcp 282 0 184.22.224.212:80 123.125.71.44:38148 CLOSE_WAIT - tcp 171 0 184.22.224.212:80 220.181.108.113:48580 CLOSE_WAIT - tcp 0 7232 184.22.224.212:22 112.96.130.11:9606 ESTABLISHED 32620/0 tcp 458 0 184.22.224.212:80 124.227.104.75:63147 ESTABLISHED - tcp 0 0 184.22.224.212:80 221.5.67.196:52738 ESTABLISHED - tcp 235 0 184.22.224.212:80 106.187.41.8:49376 CLOSE_WAIT - tcp 240 0 184.22.224.212:80 124.115.4.201:32776 CLOSE_WAIT - tcp 1737 0 184.22.224.212:80 61.131.125.240:2235 CLOSE_WAIT - tcp 235 0 184.22.224.212:80 106.187.41.8:49375 CLOSE_WAIT - tcp 425 0 184.22.224.212:80 119.146.220.35:8242 CLOSE_WAIT -
真想用回自己写的服务器,但是好不容易转移到apache2了,又不甘心。
今晚,我换了worker-mpm的多线程工作模式,尝试使用ServerLimit把进程限制为1个,结果发现apache2还是会启动4个进程。不明白。我把最大连接数MaxClients设置为30,然后启动apache2,我发现有一个apache2的进程占用的内存达到250MB之多。
root@244754:/etc/apache2# ps aux|grep apa root 1926 0.0 0.6 6104 3240 ? Ss 00:22 0:00 /usr/sbin/apache2 -k start www-data 1927 0.0 0.3 5464 1932 ? S 00:22 0:00 /usr/sbin/apache2 -k start www-data 1930 0.0 0.3 6096 1884 ? S 00:22 0:00 /usr/sbin/apache2 -k start www-data 1931 0.0 0.5 268628 3084 ? Sl 00:22 0:00 /usr/sbin/apache2 -k start root 1965 0.0 0.1 1876 660 pts/2 S+ 00:22 0:00 grep --color=auto apa
250/30 = 8MB,这不正好是Linux下默认线程堆栈的大小吗?如果我把这个堆栈大小设置为800KB,那不就只占用我十分之一,即25MB的内存了?
上网查了一下,用ThreadStackSize来设置堆栈大小,我设置了512KB,这个应该影响不大吧,我自己写的Home Server里每个线程也只使用128KB的内存而已呢!!!但是就是担心apache2里的一些模块使用的堆栈内存比较多,导致进程异常退出。
结果,内存占用果然吃惊地小了,我笑了。。。
root@244754:~# ps aux|grep apa root 1501 0.0 0.6 6104 3240 ? Ss 00:35 0:00 /usr/sbin/apache2 -k start www-data 1504 0.0 0.3 5464 1932 ? S 00:35 0:00 /usr/sbin/apache2 -k start www-data 1505 0.0 0.3 6096 1884 ? S 00:35 0:00 /usr/sbin/apache2 -k start www-data 1506 0.0 0.4 22216 2400 ? Sl 00:35 0:00 /usr/sbin/apache2 -k start root 1540 0.0 0.1 1876 660 pts/0 S+ 00:35 0:00 grep --color=auto apa
apache2的内存降下来了,php占用的内存还是蛮高的,
root@244754:~# ps aux|grep php www-data 1544 6.0 6.1 55972 32276 ? S 00:36 0:10 /usr/bin/php5-cgi www-data 1548 1.4 3.8 43892 20160 ? S 00:36 0:02 /usr/bin/php5-cgi root 1559 0.0 0.1 1876 656 pts/0 S+ 00:39 0:00 grep --color=auto php
不知道如何设置PHP占用的线程堆栈内存大小,但是有个方法似乎是通用的。ulimit!
root@244754:~# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 20 file size (blocks, -f) unlimited pending signals (-i) 16382 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
设置stack size,改为512KB,8MB实在是太浪费了。
root@244754:~# ulimit -s 512 root@244754:~# service apache2 restart * Restarting web server apache2 [ OK ] root@244754:~# ps aux|grep php www-data 1639 12.1 3.8 36384 20156 ? S 00:39 0:00 /usr/bin/php5-cgi root 1642 0.0 0.1 1876 656 pts/0 S+ 00:39 0:00 grep --color=auto php
似乎有点儿效果,不过php占用内存一直比较大,可能是模块多了吧,特别是某些图形处理的模块,在Python里也吃很多的内存。
到现在总算松了一口气了,内存用尽的问题解决了,网站访问不了的问题也解决了。不过事情还没完呢,burst给我发了一封邮件,因为维护原因,我的VPS会在11月1日,6A.M. – 2P.M. PDT之间有可能4小时左右的停止服务,大概是在北京时间晚上9点之后?我不大会算。
现在配置的多线程小内存的apache2如下:
<IfModule mpm_worker_module> StartServers 1 ServerLimit 4 MinSpareThreads 25 MaxSpareThreads 75 ThreadsPerChild 40 MaxClients 120 MaxRequestsPerChild 1000 ThreadStackSize 500000 </IfModule>
我不是很懂这些参数的意思,但是靠字面上的理解,就这么的设置了。
运行状况:
root@244754:/etc/apache2# ps aux|grep apache root 1888 0.0 0.6 6156 3288 ? Ss 01:26 0:00 /usr/sbin/apache2 -k start www-data 1889 0.0 0.3 5464 1928 ? S 01:26 0:00 /usr/sbin/apache2 -k start www-data 1892 0.0 0.3 6096 1988 ? S 01:26 0:00 /usr/sbin/apache2 -k start www-data 1893 0.3 1.4 23400 7472 ? Sl 01:26 0:01 /usr/sbin/apache2 -k start root 1949 0.0 0.1 1876 660 pts/3 S+ 01:32 0:00 grep --color=auto apache
我一直还以为你是使用nginx。。。。。apache好像是最耗内存的啊 openvz又要你配置得好才能不超标。。。。。xen好像会人性化一点 不会直接死掉进程。。
nginx也很吃内存吧,我觉得像我现在这样配置的apache也很省内存呀。
http://lab.xiaoxia.org/server/request/cHMgYXV4
nginx不耗内存,但是连接数多会502……
已经在使用,非常省内存 😀
webbench一下,包你502……
我不太喜欢nginx,可惜apache的prefork不太给力,就加了个varnish上去,现在用得还行吧……
我现在很多网站都使用nginx做代理了,熟悉了,配置很简单,也觉得很好用。
比如我的 http://dianying.fm/ ,在VPS上首页的benchmark有500 requests/second。
不会设置nginx做前端……试过学者军歌的LNMPA的那些配置文件搞了个,效果就像没nginx一样……
可怜的娃,那么在乎内存的话,还是趁早投靠nginx吧。
话说一个突发几十的windows+apache2也吃了1G多内存
还似乎用不着,说不定配置好了,我可以写一篇最省内存的Apache配置方案。
不折腾会死星人
进程:
http://lab.xiaoxia.org/server/request/cHMgYXV4
内存:
http://lab.xiaoxia.org/server/request/ZnJlZSAtbQ==
有时间写来看看
我目前用的是nginx+apache
= = 为神马不用nginx…
为何不考虑lighttpd?
好像是更轻量。。只是曾经用vps的时候从apache换到nginx突然发现内存压力一下轻松了好多。。可能是我apache优化不够。。但的确apache一直就被人说是功能强大但太臃肿了。。而且当时nginx有很多优化经验可以借鉴。。比如http://www.vpsee.com/2009/06/can-a-64mb-vps-serve-1000pvs-per-day/
静态页面,1000pvs,其实用c写一个基于select模型的http传输服务器,基本上只用不到5MB的内存左右就能够招待1000pvs。而且有很多嵌入式的迷你Web服务器程序,都是小内存,高效率设计的,不会有像nginx那么强的代理功能。
如果要考虑1000以上的并发量,就需要考虑使用基于event模型的技术了。
使用apache主要是因为它比较普及,很多项目都离不开它,而且它具有很强的可配置能力,只不过默认安装的配置比较臃肿,需要优化。
干脆自己编译个Linux Kernel放进去算了。
不行的吧,OpenVZ的VPS是共享一个Linux内核的。
小虾什么时候给讲解一下event模型的技术~
唉,生病好了再说,今天感冒……
买84机器就是悲催…
我已经从VPS走向了物理机
上了一台4G内存的I3机器…
纯AP运行无压力…
哇!!!不如贡献出来,我帮你配置一个OpenVZ,来出售VPS好了。。。我大概也了解了84的VZ配置方案。
这个可不行 嘿嘿 羡慕我吧…
对哦… 来个连接吧
怎么连接呢? 我还没打开你的网站啊,是不是太慢了,也不能ping通哦。
速度刚刚的 … 难道又意外? ping返回IP吗?
有IP,就是很慢,非常慢,一直等待无法打开主页的那种。应该是跟我用移动的网络有关???要不你用你的移动号码的手机上上试试?
给你踩下,嘻嘻
Nginx 可不吃内存。我们的配置一样的。
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 2468 1324 ? Ss Dec05 0:00 init
root 1142 0.0 0.1 5472 912 ? Ss Dec05 0:00 /usr/sbin/sshd
nobody 1158 0.0 0.5 5396 3024 ? Ss Dec05 0:00 /usr/sbin/openvpn –writepid /var/
root 1162 0.0 0.1 8708 1040 ? Ss Dec05 0:00 nginx: master process /usr/sbin/ng
www-data 1163 0.0 0.5 8952 2960 ? S Dec05 0:20 nginx: worker process
www-data 1164 0.0 0.5 8944 2956 ? S Dec05 0:19 nginx: worker process
www-data 1169 0.0 0.5 8676 2868 ? S Dec05 0:16 nginx: worker process
www-data 1170 0.0 0.5 8940 2968 ? S Dec05 0:17 nginx: worker process
root 1174 0.0 0.5 30076 2908 ? Ss Dec05 0:12 php-fpm: master process (/etc/php5
mysql 1198 0.0 3.2 57512 16820 ? Ssl Dec05 0:05 /usr/sbin/mysqld
root 1645 0.0 0.5 8332 2744 ? Ss 04:54 0:00 sshd: fwd [priv]
fwd 1656 0.0 0.7 10436 4196 ? S 04:54 0:02 sshd: fwd
root 3242 0.0 0.5 8332 2744 ? Ss 14:09 0:00 sshd: fwd [priv]
fwd 3253 0.0 0.5 9072 2784 ? S 14:09 0:00 sshd: fwd
heiher 3292 0.1 4.0 45312 21112 ? S 14:37 0:01 php-fpm: pool heiher
heiher 3295 0.0 3.9 44776 20764 ? S 14:37 0:01 php-fpm: pool heiher
heiher 3296 0.1 3.9 44796 20800 ? S 14:37 0:01 php-fpm: pool heiher
heiher 3297 0.0 4.0 45112 21088 ? S 14:37 0:01 php-fpm: pool heiher
heiher 3298 0.0 3.6 43220 19156 ? S 14:37 0:00 php-fpm: pool heiher
heiher 3299 0.1 3.9 44844 20896 ? S 14:37 0:01 php-fpm: pool heiher
root 3314 0.0 0.5 8332 2768 ? Ss 15:02 0:00 sshd: heiher [priv]
heiher 3325 0.0 0.3 8332 1700 ? S 15:02 0:00 sshd: heiher@pts/0
heiher 3326 0.0 0.3 4488 1848 pts/0 Ss 15:02 0:00 -bash
heiher 3340 0.0 0.1 2644 1008 pts/0 R+ 15:02 0:00 ps aux
total used free shared buffers cached
Mem: 524800 257048 267752 0 0 0
-/+ buffers/cache: 257048 267752
Swap: 0 0 0
128的XEN都嫌大,空闲了30M内存,用的nginx,放了五六个网站。安装apache我估计内存肯定不够用。
优化apache占内存也不多,关键是php占的内存。而且我用的php是non thread safe的,出错的机率不低。
小虾。。我想换个lnmp搭建网站方案了。。那个VPS搭建的lnmp 每隔几天就出现502错误。。重启了lnmp也无效。。但直接重启VPS就可以。。好麻烦。。你博客的系统是什么啊?用什么搭建的呢?