翻译自:Ezra Zygmuntowicz, “Xen and the Art of Rails Deployment”
听到Rails部署这两词,可能你首先想到的是下面这堆东西:
- CGI
- Apache1.3/mod_fastcgi
- Lighttpd/fcgi
- Apache2/mod_fcgid
- Lighttpd/SCGI
- Lightspeed
但时代已经变了,新时代需要新思维
Mongrel:The year of the dog
Mongrel是由Zed Shaw完成的一个HTTP Server,它:
- 使用Ragel + C的快速HTTP解析
- 使用C的快速URI过滤器
- 堆栈式请求处理
- 配置灵活
- 安全同时兼容RFC的HTTP解析器
Mongrel就足够了?
答案是:不够,因为:
- Rails请求分发需要使用互斥锁
- 一个Mongrel实例只能同时处理一个请求
- 需要使用Mongrel_cluster创建多个实例来获取可伸缩性
因此,你仍然需要一个前端HTTP Server,幸好有一大堆:
- Pen,Pound,Balance,Haproxy(不支持静态文件,只是代理)
- Lightspeed,支持静态文件和代理
- Apache2.2.x/mod_proxy_balancer,同上
这就搞定了?还不行:
- Pen(不支持SSL,不能限制连接速率)
- Pound(不支持高负载,不能限制链接速率)
- Haproxy(可限制连接速率,性能非常高,不支持静态文件
- Lightspeed,免费版功能严重残缺
- Apache2.2.x,没什么不好,就是:太臃肿了
那怎么办?
Nginx:From Russia, with Love
Nginx有什么好处:
- 专为性能优化而开发,性能是其最重要的考量
- 非常小的资源占用
- 经过考验的高负载支持,没有内存泄漏
- 杀手级的Rewrite及Proxy模块
- 平易近人的作者以及快速扩大的社区
答案有了:Nginx + Mongrel,现在
- Apache很清闲了,它只需要负责mod_dav_svn就可以了
- 灵活的nginx.conf语法可以很轻易的搞定Rails Cache及动态请求
- 还有就是:快,快,快
- 我有说过快吗?
当然还有一些问题:
- Nginx会自动缓冲文件上传,因此将失去mongrel_upload_progress支持
- Proxy模块暂时还不支持链接速率限制
完美的部署就这样产生了:
- Linux
- Nginx
- Mongrel(Mongrel_cluster)
- Monit
就这么完了?还有一点,上面讲到过Mongrel的问题:
- 不能同时处理多个请求
- Rails分发需要取得互斥锁,
- 还有多线程切换
这些都会损耗性能,因此我们需要新思维
Swiftiply: Evented Mongrel
Swiftply事实上是Mongrel的修订版,那么它对Mongrel做了什么:
- 去除了Mongrel中对线程和Socket的处理
- 使用EventMachine的事件循环来代替
- Mongrel成了单线程,事件驱动
- 显著的速度及IO吞吐量提升
- 即使高并发,也没有不良症状(性能下降及内存泄漏)
你可能疑惑为何单线程会优于多线程,这是因为:
- Ruby的绿色线程进行上下文切换时需要拷贝大量的状态信息
- 互斥锁非常昂贵
- 单个进程的IO吞吐量有限
- 事件驱动意味着更紧凑的循环已经回调处理
- 由于节省了进程切换的时间,因此单线程可以将更多的精力集中到网络IO上。
Swiftiply还有一个好处:它可以启动多个Mongrel,但只使用一个端口。
总算结束了,原文还有一部分是关于虚拟机和磁盘阵列的,对这部分不是很熟悉,所以没有翻,有兴趣的可以看原文:Xen and the Art of Rails Deployment

