对一篇关于RoR部署方案文章的疑问

这两天从Google Reader的Friends’ Shared Items中,好几个朋友都分享了同一篇文章,题目是”RoR部署方案深度剖析“,因为自己对这个内容也很感兴趣,仔细读了一下.应该说是很有意思的一篇文章,我也从中学到了不少东西,但是也发现了一些问题:

Apache/Nginx的接收缓冲区都只开了8KB,如果页面比较大,Mongrel就没有办法一次性把数据全部推给Web服务器,必须等到Web服务器把接收缓冲区的8K数据推到客户浏览器端以后,清空缓冲区,才能接收下一个8KB的数据。这种情况下,Mongrel必须和Web服务器之间进行多次数据传输,才能完成整个Web响应的过程,显然没有一次性把页面数据全部推给Web服务器快。

只有几个问题,application layer的读缓存和读的次数是否影响到socket另一端写socket的次数的? 写socket的次数是否和另一段socket read的次数对应? Web服务器向到客户端socket的写操作在什么情况下会被阻塞? 文中的一些观点和说法好像多少混淆了应用层和传输层的概念.

我们假设使用服务器端程序控制带权限的文件下载,某用户下载的是一个100MB的文件,该用户使用了多线程下载工具,他开了10个线程并发下载,那么每个线程Mongrel在响应之后,都会把整个文件读入到内存的StringIO对象当中,所以总共会创建出来10个StringIO对象保存10份文件内容,所以Mongrel的内存会一下暴涨到1GB以上。而且最可怕的是,即使当用户下载结束以后,Mongrel的内存都不会迅速回落,而是一直保持如此高的内存占用,这是因为Ruby的GC机制不好,不能够及时进行垃圾回收。

Mongrel处理rails request和静态文件使用的是不同的handler.处理静态文件用的是DirHandler,DirHandler没有通过调用response的start方法使用到StringIO,而是直接调用了response的send_file方法,直接write socket.验证过程非常简单,自己起一个mongrel,在public下放一个100M的文件,通过浏览器下载一下.在我的mac上,本来是76M的mongrel,在下载结束后是74M,下载过程中也一直小于80M,最低到过68M.无论是过程中还是结束后,都没有出现占用内存暴涨的现象.

另外,mongrel本不应该用来处理静态文件,该文章开始的图也画得很清楚.

我们知道Mongrel在使用Lighttpd的时候,可以达到最快的RoR执行速度,但是Lighttpd当前的1.4.18版本的HTTP Proxy的负载均衡和故障切换功能有一些bug,因此一般很少有人会使用这种方式。

Lighttpd 1.5重写了mod_proxy_core,sqf方式下的balancer已经没有这个问题.

而Mongrel就简单了,gem install mongrel安装完毕,mongrel_rails start启动,哪个人不会?毕竟绝大多数开发人员和部署人员不是高手,他们熟悉哪种方式,自然就会推崇哪种方式。

首先,我不太赞同复杂的就好,简单的就不专业这样的观点,Unix philosophy也不是这样的.其次,mongrel也不是mongrel_rails start就能部署到产品环境的.

11 thoughts on “对一篇关于RoR部署方案文章的疑问

  • 呵呵,两个Robin的文章都很精彩!

    对于“毕竟绝大多数开发人员和部署人员不是高手,他们熟悉哪种方式,自然就会推崇哪种方式”这种说法我也很不赞成。

  • 从昨天的log来看,财帮子”200 OK状态的Ruby动态请求”在一百九十万以上,
    更正:因为时间段问题,上面的数据有误。当日财帮子”200 OK状态的Ruby动态请求”应该是一百万,其他非休息日基本分布在80万到170万之间,特此更正。

  • JavaEye的robbin说的是
    “我们假设使用服务器端程序控制带权限的文件下载”
    通常用send_file,和你说的public download不是一回事

  • 我从来没有说过什么public download.我只是说不应该用mongrel处理静态文件.是否说不用mongrel处理静态文件就不能使用服务器程序控制带权限得文件下载?那是你的问题了.当然,即使用mongrel处理静态文件也不会出现内存暴涨.

  • 请问,”200 OK状态的Ruby动态请求”具体指什么?是否包括图片, JS, CSS之类的静态文件请求,还是仅仅由rails处理的动态 request?我是用mongrel+apache,但是apache log文件里面是2者都会打出来,如果想单独统计mongrel处理的rails 动态请求,又得打开它的log,当心会影响性能。

    我们目前是用一台web服务器+一台数据库,估计每天的动态请求在15W左右,web服务器的CPU负载平均在35%,而数据库负载不到10%
    JavaEye的70W和财帮子 的190W实在是太高了,不知道你们有多少台服务器处理?

  • 不包括静态文件,仅仅由rails处理的动态request,这个数据是从rails的production log里统计来的.
    production log很有用的,还是打开好.
    服务器目前也是一台web服务器+一台数据库

Comments are closed.