昨天VPS突然挂掉了。我晚上玩推特时才发现(choqok更新不到数据了)。不过浏览器Opera里的twitter.com代理还能用,于是我就没管,以为是网络连接问题。
不过睡前看告警邮件,发现全系列的网络访问都不能进行,PING也失败,开始怀疑VPS死机了。。。
今早起来,在Control Panel上看VPS上的状态,提示的还是绿色的“Online”(你妹的,后来发现只要电源开着就算是Online!),但显然SSH已经无法连接上去了。
场景介绍完毕,顺便讲述背景
我的VPS是这款 Hostigation 上的KVM 128m,前几天买着玩,发现网络很好(什么pr路线啥的我也不懂),访问速度比之前的directspace快一些些(对于我这种被教育网毒害若干年的,内心一直怀着对网速的渴望)。这个KVM机器后台有个VNC登录界面,是Java Applet,于是捣鼓了一下(顺便吐槽一下openjdk-plugin,弱爆了),成功登录机器——结果看到界面后我惊呆了:
内存用完了啊亲!久违的Kernel Panic啊亲!!我第一次知道内存爆掉会连着内核也爆啊!!吐槽不能……只能默默的点击页面上的Reboot按钮……
深入内核被爆的秘密
其实内存不足的原因我也能大概猜到,机器上跑的是nginx + php5-fpm + wordpress。fpm这货根本就是内存大户,VPS上又只有128M内存+256M Swap,Wordpress博客又慢又胖,VPS上的CPU又不给力,监控宝还在其他地方默默地发起请求访问博客首页……所以访问不能承受之重,VPS内存溢出了。
为了验证,我祭出压力测试工具ab2(就是apache带的工具),首先小试一招:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $ ab2 http://banjuan.net/blog/ …… Total transferred: 25862 bytes HTML transferred: 25642 bytes Requests per second: 0.48 [#/sec] (mean) Time per request: 2075.089 [ms] (mean) Time per request: 2075.089 [ms] (mean, across all concurrent requests) Transfer rate: 12.17 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 196 196 0.0 196 196 Processing: 1879 1879 0.0 1879 1879 Waiting: 1457 1457 0.0 1457 1457 Total: 2075 2075 0.0 2075 2075 |
悲催地看到,请求处理时间为1879ms。。。接近两秒啊!而从后台top命令可以看到 [php-fpm: pool www]这个进程突然冒出来,然后吃住20M内存不动了。。。
再来一次强大的招式,每秒并发10个请求,一共请求100次,看看啥情况:
1 2 3 4 | $ ab2 -n 100 -c 10 http://banjuan.net/blog/ ... apr_poll: The timeout specified has expired (70007) Total of 3 requests completed |
偶也,跑了一分钟后突然来了一句超时,压力测试工具自动停了。这时候VPS上的悲惨状况我就不截图了(当时也没截图),内存已经彻底不够用,256M SWAP都快分配完毕了,幸好在悲剧重演之前,ab2工具自己停掉了,呼!看着岌岌可危的VPS,看着进程列表中满眼的 php-fpm,我只好默默地把他们都重启掉。。。
娇小的VPS果然不能承受野蛮的访问
研究出是php5-fpm的问题后,那就容易办了。按每个fpm进程20M内存占用来算,VPS上最多只应该启动5个进程;另外考虑到咱的博客基本没访问量,所以空闲fpm进程就设置为少一些吧。另外,也限制一下请求处理的时间,避免排队排到死:
1 2 3 4 5 | pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 2 request_terminate_timeout = 15 |
这一次,再跑ab2压力测试工具,总算能够活下来了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | $ ab2 -n 100 -c 10 http://banjuan.net/blog/ …… Concurrency Level: 10 Time taken for tests: 453.626 seconds Complete requests: 100 Failed requests: 44 (Connect: 0, Receive: 0, Length: 44, Exceptions: 0) Write errors: 0 Non-2xx responses: 34 Total transferred: 1582999 bytes HTML transferred: 1563330 bytes Requests per second: 0.22 [#/sec] (mean) Time per request: 45362.583 [ms] (mean) Time per request: 4536.258 [ms] (mean, across all concurrent requests) Transfer rate: 3.41 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 196 202 3.9 201 219 Processing: 1943 43170 13715.5 46237 63341 Waiting: 1524 37434 13529.3 37333 60571 Total: 2142 43372 13715.4 46435 63540 Percentage of the requests served within a certain time (ms) 50% 46435 66% 52552 75% 54373 80% 56466 90% 58586 95% 60083 98% 60781 99% 63540 100% 63540 (longest request) |
不过,悲惨地看到请求时延平均增长到了6秒。。。可见排队之长。。。
请求量之禅
这一次的事件告一段落了。不过有关这个请求量、处理时间的数值却引起我的思考。
目前这个弱小的kvm虚拟机,良好情况下,一个请求要消耗 2s,进程数限制是最多 5 个进程,这样所能承受的每秒最大请求是 2.5 r/s 。真是一个微小的数字。。。
在我的实际工作中,公司里的WEB机器跑的还是古老的C++写的CGI,一般单个CGI进程承受的访问量是 10r/s ~ 20r/s,机器配置是酷睿CPU+8G内存,一般CGI开50个进程(还同时跑着其他CGI),单机CGI承受量为500r/s(目前最高的我见过有1600r/s)。这时机器负载还算是正常服务,性能消耗还留有余地,一般CPU占用为30%,负载小于1,能再承受50%的高峰访问。
或许会问,有必要追求这个高的访问承受力吗??实际上,我们公司的CGI部署起来,很少只用1台机器就够的。多数情况下,需要用4台以上(刚才提到的那个1600r/s的CGI),有些极高访问量的CGI会有每秒1万次请求,如果单机以 500r/s算,那么需要20台服务器组成集群来处理。而这些机器还只是专门跑WEB服务器的,DB还是另外独立部署,所以后面还有一大堆的DB机器……这些都是赤裸裸的钱啊……
所以,VPS什么的,真的是只能玩玩,搭个没访问量的个人博客。弱爆了唉。。。

……你的那个vps也太弱了吧……
@csslayer
哈哈。因为内存太小,CPU也弱。
刚才顺便也压测了一下csslayer.tk 和 DirectSpace 512M的VPS。对比起来,还是burst的CPU强劲一些。
不过burst的缺点也是明显的,压测拉去README静态文件,nginx的CPU、MEM占用竟然能够彪得比fpm的php访问还夸张,IO性能实在是雷人。
而且burst的网速真的是太慢慢慢慢了!!!SSH登录明显感觉到延迟啊!!!
偶然路过贵博客,发现有本人小站VPS的评测,不过现在已经换到虚拟主机了,也是因为wordpress太耗内存了,用VPS完全是费钱啊,求链接,我那边已经把贵站的链接做好了,谢谢!