石锅拌饭

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

by Robin Lu on Jan.15, 2008, about , , ,

这两天从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 Comments for this entry

  • Robert

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

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

  • 老熊

    好文,事情越辩越明

    同样作为ror开发网站,不知道财帮子和javaeye,哪个流量大;-)

  • Robin Lu

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

  • whocare

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

  • Robin Lu

    我从来没有说过什么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实在是太高了,不知道你们有多少台服务器处理?

  • Robin Lu

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

  • kotil

    http://www.javaeye.com/topic/156353
    Javaeye里看到了robbin对此篇文章的回应。

  • 烦了robin

    Java eye的robin水平还是有些的,但是那种傲慢武断的口气让人厌烦

  • 老熊

    NND还有人冒充我,第一个是我,第二个是who?

Search

Archives

Browse by tags

agile apple blog book design ecto extension firefox git google hack ichm iphone keyword life mac madfox movie nonsense opensource plugin pm ruby rubyonrails sns software startup wordpress work 财帮子