原文:http://stackoverflow.com/questions/4113299/ruby-on-rails-server-options
 
 
一,Apache vs Nginx
 
     他们都是web服务器,都能伺服静态文件,利用恰当的模块也能伺服动态的web应用。Apache更加流行,拥有更多的功能;Nginx则相对小巧、快速、功能少。
 
     Apache 和 Nginx都能在盒子外(out-of-the-box)伺服Ruby服务器,为此你需要使用另外的插件来组合他们。
 
     Apache 和 Nginx都能作为反向代理,就是说他们能够把进来的 HTTP 请求发给其他服务器,接着把该服务器的 HTTP 响应转给客户端,后面会看到为什么和这个有关系。
 
二,Mongrel以及其他production环境的服务器 vs WEBrick
 
     Mongrel是Ruby实现的应用服务器,具体来说:
 
1,在自己的进程空间中加载 Ruby 应用。
2, 创建一个 TCP socket,允许它可以和外部世界通信(例如Internet)。Mongrel 在这个socket上监听 HTTP 请求,并把请求数据转发给 Ruby 应用。
3,Ruby 应用返回一个描述 HTTP 响应的对象,Mongrel 将其转换为真正的 HTTP 响应字节,并发回到 socket 中。
 
     然而 Mongrel 已经不再维护了,其他替代的服务器是:
  • Phusion Passenger
  • Unicorn
  • Thin
  • Puma
  • Trinidad (JRuby only)
  • TorqueBox (JRuby only)
     接下来我会讲一讲他们和 Mongrel 的区别
 
     WEBrick 和 Mongrel 很像,区别如下:
  • WEBrick 不适合用于 production。WEBrick 完全是用 Ruby 写的;Mongrel( 以及其他 Ruby 应用服务器)是部分 Ruby 部分C,主要是 Ruby,但它的 HTTP 解析器为了性能是用 C 写的。
  • WEBrick 速度比较慢而且不够强壮,有普遍知道的内存泄漏问题,以及 HTTP 解析问题。
  • 因为 WEBrick 是 Ruby 默认自带的,所以 WEBrick 经常用于 development 环境下作为默认服务器,而其他的服务器则需要另外安装。不建议在production 环境下使用 WEBrick 服务器,虽然因为某些原因,Heroku 选择了WEBrick 作为默认服务器,他们以前使用的是 Thin,但我不知道他们为什么换到了 WEBrick。
 
三,应用服务器世界
 
     当前所有的Ruby 应用服务器都是 HTTP 类型的,一些服务器直接将80端口暴露到 Internet 中,另一些则没有。
  • 暴露80端口的:Phusion Passenger, Rainbows。
  • 没有直接暴露的:Mongrel, Unicorn, Thin, Puma。这些服务器必须必须置于反向代理服务器之后,比如Apache 和 Nginx。
  • 我不了解 Trinidad 和 TorqueBox,所以就忽略了。
 
为什么有些服务器需要置于反向代理之后?
 
  • 某些服务器的每个进程在同一时间只能处理一个请求,如果想同时处理两个请求,你就需要启动多个服务器实例,都伺服同一个 Ruby 应用。这种应用服务器进程的集合称为应用服务器集群(比如Mongrel Cluster, Thin Cluster)。然后你必须启动 Apache 或者 Nginx,给集群做反向代理,Apache/Nginx 会处理好集群中不同应用实例间的请求分发。(更多内容参见章节 "I/O并发模型”)
  • Web 服务器可以缓存请求和响应。有些客户端发送数据、接收数据的速度缓慢,你当然不希望应用服务器在等待客户端收发数据时什么也不干,Web 服务器可以隔离应用服务器和慢客户端。Apache 和 Nginx 擅长同时很多事情,因为他们是多线程或者基于事件的。
  • 大多数的应用服务器可以伺服静态文件,但不擅长,而Apache 和 Nginx可以更快速度处理这件事情。
  • 人们经常直接使用Apache 或者 Nginx伺服静态文件,而不会处理需要转发的请求(forward requests),这是比较安全的策略。Apache 和Nginx足够聪明,可以保护应用服务器远离恶意请求。
 
为什么有些服务器可以直接暴露在Internet中?
  • Phusion Passenger 和其他应用服务器不一样,其中一个特点是可以融入其他服务器。
  • Rainbows 的作者公开指出,Rainbows 可以直接暴露在 Internet 中。他非常确认在解析 HTTP 过程中不会轻易遭受攻击。still, the author provides no warranty and says that usage is at own risk.
 
四,应用服务器对比
 
     在这一章中,我会比较我提过的大多数服务器,但不包括 Phusion Passenger。Phusion Passenger 和其他的不一样,我会单独开出一章。我还会忽略 Trinidad 和 TorqueBox,因为我对他们不是很了解,只有你用到 JRuby 的时候才会涉及到他们。
 
  • Mongrel 是块暴露的石头。像之前提到的,Mongrel 仅仅是单线程、多进程,所以它只用于集群(cluster)中。没有进程监控,意味着如果集群中一个进程崩溃了,则需要手动重启。人们需要使用额外的进程来照看 Mongrel,比如 Monit 和 God。
  • Unicorn 是从 Mongrel 中fork出来的。支持监控一定数量的的进程:如果一个进程崩溃了,则会被主进程自动重启。它能让所有进程都监听同一个共享的socket,而不是每个进程使用单独的socket,这会简化反向代理的配置。像Mongrel一样,Unicorn 是单线程、多进程。
  • Thin 利用 EventMachine 库,实现基于事件的 I/O 模型。它并不是使用 Mongrel 的 HTTP 解析器,没有基于 Mongrel。它的集群节点没有进程监控,所以你需要去监控进程是否崩溃。每个进程监听各自的socket,不像 Unicorn 一样共享socket。理论上来说,Thin 的I/O 模型允许高并发,这也是 Thin 被应用的大部分场合。一个 Thin 的进程只能处理一个并发请求,所以你还需要集群。关于这个古怪的性质,更多内容参见“I/O并发模型”。
  • Puma 也是从 Mongrel 中fork出来的,但和 Unicorn 不一样的是,Puma 被设计成多进程的。目前不支持集群。你需要特别确认的是你能实现多核(You need to take special care to ensure that you can utilize multiple cores)。更多内容参见“I/O并发模型”。
  • Rainbows 通过给不同的库实现多种并发模型
 
五,Phusion Passenger
 
     Phusion Passenger 和其他的不一样。他直接融入 Apache 或者 Nginx,类似于 Apache 的 mod_php。就像 mod_php 使 Apache伺服 PHP 应用一样, Phusion Passenger 也可以使 Apache 或者 Nginx 伺服 Ruby 应用。Phusion Passenger 的目标是所有的事情做起来尽可能地减少麻烦。
 
     如果使用 Phusion Passenger的话,你不需要为你的应用启动一个进程或者集群,为 Apache/Nginx 配置静态目录,或者设置反向代理。
     你只需要:
  1. 编辑web服务器的配置文件,写入 Ruby 应用下public文件夹的路径
  2. 没有第二步。
 
     所有的配置工作都在Web 服务器配置文件的指导下做完了,Phusion Passenger几乎自动化了所有事情,不需要启动集群以及管理进程。启动或者停止进程,他们崩溃时重启,这些都被自动化了。和其他应用服务器相比,Phusion Passenger 所需要做的改动工作非常少,这是人们使用 Phusion Passenger 的主要原因。
     和其他应用服务器不同的是,Phusion Passenger 主要是用 C++ 写的,速度很快。
     Phusion Passenger 的企业版有更多的特性,比如自动回滚重启,支持多线程,容错部署。(such as automated rolling restarts, multithreading support, deployment error resistance, etc.)
 
     基于以上原因,Phusion Passenger是当前最流行的 Ruby 应用服务器,服务于超过50,000 站点,包括大型站点:New York Times, Pixar, Airbnb。
 
六,Phusion Passenger vs 其他服务器
 
     相对其他的服务器,Phusion Passenger 提供了更多的特性功能
  • 根据访问量自动调整进程的数量。在资源有限的服务器上,我们运行多个 Ruby 应用,而我们的应用不对外公开,而且组织内的访客每天的访问量也很低,例如 Gitlab, Redmine等。Phusion Passenger 能够在进程不使用的时候挂起他们,需要的时候恢复进程,为更重要的应用腾出资源。相比之下,其他的服务器的所有进程会一直运行着。
  • 有些服务器不适合某些特定的负荷。例如 Unicorn 为轻量快速的请求而设计,See the Unicorn website section "Just Worse in Some Cases".
          Unicorn 不擅长的负荷:
               > 流(e.g. Rails 4 live streaming or Rails 4 template streaming)
               > 调用 HTTP API 
Phusion Passenger Enterprise 4及后续版本中多种I/O模型,使它非常适合这种负荷。
  • 其他的应用服务器需要用户为每个应用至少启动一个实例,相比之下,Phusion Passenger 支持一个实例多个应用。这大大减少管理员的开支。
  • Phusion Passenger 支持多个 MRI Ruby, JRuby 和 Rubinius。Mongrel, Unicorn 和 Thin 只支持 MRI,Puma也支持三个。
  • Phusion Passenger 不仅支持 Ruby,它还支持 Python WSGI,所以同样能运行 Django 和 Flask 应用。实际上,Phusion Passenger正在向多语言服务器发展的道路上前进,Node.js的支持已经列在计划中。
  • Out-of-band garbage collection。Phusion Passenger 可以在请求的循坏外执行 Ruby 的垃圾回收,可以潜在地减少几百毫秒的请求时间(reducing request times by hundreds of milliseconds)。Unicorn也有类似的功能,但是Phusion Passenger 的版本更加灵活,因为 1,it's not limited to GC and can be used for arbitrary work。2,Phusion Passenger的版本适应多进程应用,而 Unicorn 则不行。
  • 自动回滚重启(Automated rolling restarts)。Unicorn 以及其他应用服务器的回滚重启需要脚本来执行,Phusion Passenger 企业版自动帮你完成了。
     还有更多的特性和优势,暂不一一列举。你可以参考全面的 Phusion Passenger 手册(Apache versionNginx version),或者到官网得到更多信息。
 
七,I/O并发模型
 
  • 单线程,多进程。Ruby 应用服务器中比较常见、流行的 I/O 模型,主要是因为 Ruby 生态系统中的多线程支持比较差。一个进程同时仅且只能处理一个请求,web 服务器通过多进程来进行均衡负载。这种模型比较稳定,开发者不会轻易造成并发bug。这种模型适合执行快速的短请求,不适合速度慢、长请求阻塞I/O的运算,例如 调用HTTP API。
  • 纯多线程。现在Ruby生态系统已经很支持多线程了,所以这种I/O模型变得切实可行。多线程支持高I/O并发,既适合短请求也适合长请求。开发者也很容易引入并发bug,幸运的是大多数框架按照这种方式设计,所以也不太可能发生。有一个需要注意的事情是,因为使用了全局解释器锁(GIL),MRI Ruby 解释器不能均衡使用多个CPU内核,即使有多个线程。为此,你可以使用多个进程,每个进程使用一个CPU内核。JRuby 和 Rubinius没有GIL,所以他们的一个进程可以均衡负载多个CPU内核 。
  • 结合多线程、多进程。Phusion Passenger Enterprise 4以后版本实现了。你可以轻易在以下模型切换:单进程多线程,纯多线程,多进程多线程。这种模型给出了最好的选择方式。
  • 事件。这种模型和之前提到的模型不一样。它允许极高的I/O并发,以及非常适合长请求。为实现此功能,需要从应用到框架的详细支持。然而主要的框架(Rails 和 Sinatra)并不支持事件模型。这也是实际上一个Thin进程同时不能处理多个请求的原因,就像单线程多进程模型一样。只有专门的框架才充分利用事件I/O模型,例如Cramp。
 
八,Capistrano
 
     Capistrano和其他的不一样。在之前的所有章节中,“部署”指的是在服务器上启动 Ruby 应用,然后对游客开放,但是在这之前需要一些准备工作,例如:
  • 将 Ruby 应用的代码和文件上传到服务器机器上。
  • 安装应用所依赖的库。
  • 创建或者迁移数据库。
  • 启动或者停止应用依赖的守护进程,例如 Sidekiq/Resque  或者 whatever。
  • 启动应用时需要做的所有其他事情。
     在 Capistrano 的语义中,“部署”意味着去做所有的准备工作。Capistrano 不是一个服务器,反而是一个自动做那些准备工作的工具。你告诉 Capistrano 你的服务器在哪里,以及每当你部署新版本应用的时候需要执行的命令,Capistrano 就能帮你上传 Ruby 应用到服务器上并且运行你指定的命令。
 
     Capistrano 总是与应用服务器组合使用,并不会替代应用服务器。反之亦然,应用服务器也不会替代 Capistrano。
 
     当然 Capistrano 也不是必须使用的。如果你可以使用 FTP 或者 手动上传 Ruby 应用,每一次都执行相同的动作。其他人厌倦这种重复,所以他们在 Capistrano 中自动执行这些步骤。
 

[ 翻译]ruby rails相关的常见服务器的更多相关文章

  1. [翻译]The Neophyte's Guide to Scala Part 12: Type Classes

    The Neophyte's Guide to Scala Part 12: Type Classes 过去的两周我们讨论了一些使我们保持DRY和灵活性的函数式编程技术,特别是函数组合,partial ...

  2. 安装 Ruby, Rails 运行环境 常见的错误

    安装部署ruby on rails 的环境时并不是想的那么顺利 这个是我遇到的问题及解决的方式 参考安装博客: (1) https://ruby-china.org/wiki/install_ruby ...

  3. [Ruby on Rails系列]4、专题:Rails应用的国际化[i18n]

    1. 什么是internationalization(i18n)? 国际化,英文简称i18n,按照维基百科的定义:国际化是指在设计软件,将软件与特定语言及地区脱钩的过程.当软件被移植到不同的语言及地区 ...

  4. [译]一个灵活的 Trello 敏捷工作流

    [译]一个灵活的 Trello 敏捷工作流 翻译自 An Agile Trello Workflow That Keeps Tasks Flexible Getting things done 可不只 ...

  5. Java基础 之软引用、弱引用、虚引用 ·[转载]

    Java基础 之软引用.弱引用.虚引用 ·[转载] 2011-11-24 14:43:41 Java基础 之软引用.弱引用.虚引用 浏览(509)|评论(1)   交流分类:Java|笔记分类: Ja ...

  6. [干货]2017已来,最全面试总结——这些Android面试题你一定需要

        地址.http://blog.csdn.net/xhmj12/article/details/54730883 相关阅读: 吊炸天!74款APP完整源码! [干货精品,值得收藏]超全的一线互联 ...

  7. Git之(一)Git是什么[转]

    为什么使用Git 孔子曾经曰过的,名正则言顺 言顺则事成. 我们在学习一项新技术之前,弄清楚为什么要学它至关重要,至于为什么要学习Git,我用一段if-else语句告诉你原因: if(你相信我){ 我 ...

  8. [整理]EABI和OABI【转】

    本文转载自:https://www.crifan.com/order_eabi_and_oabi/ 1.什么是ABIABI,application binary interface (ABI),应用程 ...

  9. 【纸模】六角大王 Super 5.6 CHS 简体中文版 U20080725+[手册]窗口与工具的概要(PDF格式)

    六角大王5.6简体中文版中文化:star21 主界面<ignore_js_op> 人体生成模式<ignore_js_op> 动画<ignore_js_op> < ...

随机推荐

  1. 13年10月 月赛第一场 set 4 迷宫问题

    题目 给定一个n*m的迷宫,如S....#E.E其中,S代表开始位置,#代表不可行走的墙,E代表出口.主人公从开始位置出发,每次等概率的随机选择下一个可以行走的位置(可能会发生回溯),直到到达某一个出 ...

  2. 如何在单片机上使用printf函数(printf)(avr)(stm)(lpc)(单片机)(转)

    摘要:    当我们在调试代码时,通常需要将程序中的某个变量打印至PC机上,来判断我们的程序是否按预期的运行,printf函数很好的做到了这一点,它能直接以字符的方式输出变量名和变量的值,printf ...

  3. js里面声明变量时候的注意事项

    变量名可以是中文,只能有下划线,$,数字和字母组成,开头只能以下划线(不建议使用)和字母开头.

  4. setTimeout/setInterval伪异步

    setTimeout(function(){alert(1);}, 1000); 在使用setTimeout.setInterval的时候,会传一个时间来控制代码的执行时机.在经过了设置的时间段后,代 ...

  5. js 数组函数

    Array.prototype.join Array.prototype.reverse Array.prototype.sort Array.prototype.concat Array.proto ...

  6. 微软雅黑的Unicode码和英文名

    中文名 英文名 Unicode编码 微软雅黑 Microsoft YaHei \5FAE\8F6F\96C5\9ED1 宋 体 SimSun \5B8B\4F53 黑 体 SimHei \9ED1\4 ...

  7. pta 习题集 5-15 数组循环左移

    本题要求实现一个对数组进行循环左移的简单函数:一个数组aa中存有nn(>0>0)个整数,在不允许使用另外数组的前提下,将每个整数循环向左移mm(≥0≥0)个位置,即将aa中的数据由(a0a ...

  8. javascript 知道这20个正则表达式,能让你少写1,000行代码

    正则表达式,一个十分古老而又强大的文本处理工具,仅仅用一段非常简短的表达式语句,便能够快速实现一个非常复杂的业务逻辑.熟练地掌握正则表达式的话,能够使你的开发效率得到极大的提升. 正则表达式经常被用于 ...

  9. php引用(&)详解及注意事项——引用返回function &a();&a()

    http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/09/10/2173092.html 函数的引用返回 先看代码 <?php func ...

  10. Python开发【数据结构】:基础

    数据结构 什么是数据结构? 简单来说,数据结构就是设计数据以何种方式组织并存储在计算机中. 比如:列表.集合与字典等都是一种数据结构 N.Wirth: “程序=数据结构+算法” 列表 列表:在其他编程 ...