首页 文章

Ruby on Rails服务器选项[关闭]

提问于
浏览
549

为我的Ruby on Rails应用程序设置开发服务器的整个问题让我很困惑 . 我确信WEBrick,Mongrel,Passenger,Apache,Nginx等等,我并不了解他们扮演的不同角色 .

我开始使用WEBrick,现在我使用Mongrel进行开发 . 这些服务器是独立的,还是它们位于Apache之前?

我读过有关Passenger的内容,我不太明白它是什么,该网站称“使Ruby Web应用程序的部署变得轻而易举”,它是否取代了Mongrel?它是否像Capistrano一样,它也部署了Web应用程序?

请记住我想测试SSL,我相信mongrel不支持,什么是最好的开发服务器设置?

谢谢

1 回答

  • 1221

    “部署”一词可以有两种含义,具体取决于具体情况 . 您还将Apache / Nginx的角色与其他组件的角色混淆 .

    历史记录:本文最初写于2010年11月6日,当时Ruby应用服务器生态系统有限 . 我已于2013年3月15日更新了本文,其中包含生态系统中的所有最新更新 .

    Disclaimer :我是Phusion Passenger的作者之一,也是应用服务器之一 .

    Apache vs Nginx

    他们都是网络服务器 . 他们可以提供静态文件,但是 - 使用正确的模块 - 也可以提供动态网络应用,例如那些用PHP编写的 . Apache更受欢迎,功能更多,Nginx体积更小,速度更快,功能更少 .

    Apache和Nginx都不能提供开箱即用的Ruby Web应用程序,为此,您需要将Apache / Nginx与某种附加组件结合使用,稍后将对此进行介绍 .

    Apache和Nginx也可以充当反向代理,这意味着他们可以接收传入的HTTP请求并将其转发到另一个服务器,该服务器也会说HTTP . 当该服务器响应HTTP响应时,Apache / Nginx会将响应转发回客户端;稍后您将了解为什么这是相关的 .

    Mongrel和其他 生产环境 应用服务器与WEBrick

    Mongrel是一个Ruby“应用程序服务器”:具体而言,这意味着Mongrel是一个应用程序:

    • 在自己的进程空间中加载Ruby应用程序 .

    • 设置TCP套接字,允许它与外界(例如Internet)通信 . Mongrel侦听此套接字上的HTTP请求,并将请求数据传递给Ruby Web应用程序 .

    • 然后,Ruby Web应用程序返回一个对象,该对象描述了HTTP响应应该是什么样子,并且Mongrel负责将其转换为实际的HTTP响应(实际字节)并通过套接字将其发回 .

    然而,杂种已经相当过时了,现在它已不再维持 . 较新的替代应用程序服务器是:

    • Phusion Passenger

    • 独角兽

    • 彪马

    • 特立尼达(仅限JRuby)

    • TorqueBox(仅限JRuby)

    我稍后将介绍它们,并描述它们彼此之间以及与Mongrel的不同之处 .

    WEBrick与Mongrel的功能相同,但不同之处在于:

    • WEBrick不适合制作,不像我之前提到过的其他内容 . WEBrick完全用Ruby编写 . Mongrel(以及大多数其他Ruby应用服务器)是Ruby和C部分(主要是Ruby),但它的HTTP解析器是用C语言编写的,用于提高性能 .

    • WEBrick速度较慢且不太稳健 . 它有一些已知的内存泄漏和一些已知的HTTP解析问题 .

    • WEBrick通常仅在开发期间用作默认服务器,因为默认情况下WEBrick包含在Ruby中 . Mongrel和其他应用服务器需要单独安装 . 不建议在 生产环境 环境中使用WEBrick,但由于某些原因,Heroku选择WEBrick作为其默认服务器 . 他们之前使用的是Thin,所以我不知道他们为什么要切换到WEBrick .

    应用服务器和世界

    所有当前的Ruby应用服务器都使用HTTP,但是某些应用服务器可能会直接在端口80上暴露给Internet,而其他服务器可能不会 .

    • 可直接暴露于互联网的应用服务器:Phusion Passenger,Rainbows

    • 可能未直接暴露于Internet的应用服务器:Mongrel,Unicorn,Thin,Puma . 这些应用服务器必须放在Apache和Nginx等反向代理Web服务器之后 .

    • 我没有't know enough about Trinidad and TorqueBox, so I'已经省略了它们 .

    为什么必须将某些应用服务器置于反向代理之后?

    • 某些应用服务器每个进程只能同时处理1个请求 . 如果要同时处理2个请求,则需要运行多个app server实例,每个实例都提供相同的Ruby应用程序 . 这组app服务器进程称为app server cluster(因此称为Mongrel Cluster,Thin Cluster等) . 然后,您必须设置Apache或Nginx以反向代理到此群集 . Apache / Nginx将负责在集群中的实例之间分发请求(有关详细信息,请参见"I/O concurrency models"部分) .

    • Web服务器可以缓冲请求和响应,保护应用服务器免受"slow clients" - 不同的HTTP客户端的影响't send or accept data very quickly. You don' t希望您的应用服务器在等待客户端发送完整请求或接收完整响应时不执行任何操作,因为在此期间应用服务器可能无法执行任何其他操作 . Apache和Nginx非常擅长同时做很多事情,因为它们要么是多线程的,要么是偶数的 .

    • 大多数应用服务器都可以提供静态文件,但并不是特别擅长 . Apache和Nginx可以更快地完成它 .

    • 人们通常会设置Apache / Nginx来直接提供静态文件,但转发请求,这些请求不具备良好的安全性 . Apache和Nginx非常成熟,可以保护应用服务器免受(可能是恶意的)损坏的请求 .

    为什么某些应用服务器可以直接暴露给互联网?

    • Phusion Passenger与所有其他应用服务器完全不同 . 它的一个独特功能是它集成到Web服务器中 .

    • Rainbows作者公开表示,将其直接暴露在互联网上是安全的 . 作者非常肯定HTTP解析器中没有漏洞(和类似的) . 尽管如此,作者仍未提供任何保证,并表示使用风险由您自行承担 .

    应用服务器进行了比较

    在本节中,我将比较我提到的大多数应用程序服务器,但不会比较Phusion Passenger . Phusion Passenger是一个与其他人不同的野兽,我给它一个专门的部分 . 我也省略了Trinidad和TorqueBox因为我不太了解它们,但是如果你使用JRuby它们只是相关的 .

    • Mongrel 非常犀利 . 如前所述,Mongrel纯粹是单线程多进程,因此它仅在集群中有用 . 没有进程监视:如果群集中的进程崩溃(例如,由于应用程序中的错误),则需要手动重新启动 . 人们倾向于使用外部过程监控工具,如Monit和God .

    • Unicorn 是Mongrel的一个分支 . 它支持有限的进程监视:如果进程崩溃,它将由主进程自动重新启动 . 它可以使所有进程侦听单个共享套接字,而不是每个进程的单独套接字 . 这简化了反向代理配置 . 与Mongrel一样,它纯粹是单线程多进程 .

    • Thin 使用EventMachine库使用事件I / O模型 . 除了使用Mongrel HTTP解析器之外,它不以任何方式基于Mongrel . 它的集群模式没有进程监控,所以你需要监控崩溃等 . 没有类似Unicorn的共享套接字,所以每个进程都监听它自己的套接字 . 理论上,Thin的I / O模型允许高并发性,但在大多数实际使用Thin的情况下,一个Thin进程只能处理1个并发请求,因此您仍然需要一个集群 . 更多关于"I/O concurrency models"部分中的这一特殊 property .

    • Puma 也是从Mongrel分叉的,但与Unicorn不同,Puma的设计纯粹是多线程的 . 因此,目前没有内置群集支持 . 您需要特别注意确保可以使用多个核心(有关详细信息,请参阅"I/O concurrency models"部分) .

    • Rainbows 通过使用不同的库支持多个并发模型 .

    Phusion Passenger

    Phusion Passenger的工作方式与其他所有工作方式完全不同 . Phusion Passenger直接集成到Apache或Nginx中,因此可以与Apache的mod_php进行比较 . 就像mod_php允许Apache为PHP应用程序提供服务一样神奇,Phusion Passenger允许Apache(以及Nginx!)几乎神奇地为Ruby应用程序提供服务 . Phusion Passenger的目标是尽可能轻松地使一切正常工作(tm) .

    不是为您的应用启动流程或集群,而是使用Phusion Passenger配置Apache / Nginx以提供静态文件和/或将代理请求反向代理请求:您只需:

    • 您编辑Web服务器配置文件并指定Ruby应用程序's ' public'目录的位置 .

    • 没有第2步 .

    所有配置都在Web服务器配置文件中完成 . Phusion Passenger几乎可以自动化所有内容 . 无需启动集群和管理进程 . 启动/停止进程,在崩溃时重新启动它们等等 - 全部自动化 . 与其他应用服务器相比,Phusion Passenger的移动部件更少 . 这种易用性是人们使用Phusion Passenger的主要原因之一 .

    与其他应用服务器不同,Phusion Passenger主要用C语言编写,速度非常快 .

    还有一个具有更多功能的Phusion Passenger,例如自动滚动重启,多线程支持,部署错误抵抗等 .

    基于以上原因,Phusion Passenger目前是最受欢迎的Ruby应用服务器,为超过150,000个网站提供支持,包括纽约时报,皮克斯,Airbnb等大型网站 .

    Phusion Passenger与其他应用服务器

    Phusion Passenger提供了更多功能和提供与其他应用服务器相比具有许多优势,例如:

    • 根据流量动态调整进程数 . 我们在资源受限的服务器上运行大量Rails应用程序,这些应用程序不面向公众,我们组织中的人员每天最多只使用几次 . 诸如Gitlab,Redmine等等.Phusion Passenger可以在重复使用这些流程时将其分解,从而为更重要的应用程序提供更多资源 . 使用其他应用服务器,您的所有进程都会一直打开 .

    • 根据设计,某些应用服务器不擅长某些工作负载 . 例如,Unicorn仅用于快速运行请求:请参阅the Unicorn website section "Just Worse in Some Cases" .

    Unicorn不擅长的工作量是:

    • 流式工作负载(例如Rails 4直播或Rails 4模板流) .

    • 应用程序执行HTTP API调用的工作负载 .

    Phusion Passenger Enterprise 4或更高版本中的混合I / O模型使其成为这类工作负载的绝佳选择 .

    • 其他应用服务器要求用户为每个应用程序至少运行一个实例 . 相比之下,Phusion Passenger在单个实例中支持多个应用程序 . 这大大减少了管理开销 .

    • 自动用户切换,方便安全功能 .

    • Phusion Passenger支持许多MRI Ruby,JRuby和Rubinius . Mongrel,Unicorn和Thin仅支持MRI . Puma也支持所有3 .

    • Phusion Passenger实际上支持的不仅仅是Ruby!它还支持Python WSGI,因此它也可以运行Django和Flask应用程序 . 事实上,Phusion Passenger正朝着成为多语言服务器的方向发展 . Node.js支持todo列表 .

    • 带外垃圾收集 . Phusion Passenger可以在正常的请求/响应周期之外运行Ruby垃圾收集器,可能会将请求时间减少数百毫秒 . Unicorn也有类似的功能,但Phusion Passenger 's version is more flexible because 1) it'不仅限于GC,可以用于任意工作 . 2)Phusion Passenger 's version works well with multithreaded apps, while Unicorn' s没有 .

    • 自动滚动重启 . 在Unicorn和其他服务器上滚动重启需要一些脚本工作 . Phusion Passenger Enterprise为您完全自动化 .

    有更多的功能和优点,但列表真的很长 . 有关信息,请参阅综合Phusion Passenger手册(Apache versionNginx version)或the Phusion Passenger website .

    I / O并发模型

    • Single-threaded multi-process. 这是传统上Ruby应用服务器最流行的I / O模型,部分原因是Ruby生态系统中的多线程支持非常糟糕 . 每个进程一次只能处理1个请求 . Web服务器在进程之间进行负载 balancer . 这个模型非常强大,程序员几乎没有机会引入并发错误 . 但是,它的I / O并发性非常有限(受进程数限制) . 此模型非常适合快速,短时间运行的工作负载 . 它非常不适合缓慢,长时间运行的阻塞I / O工作负载,例如:涉及调用HTTP API的工作负载 .

    • Purely multi-threaded. 如今Ruby生态系统具有出色的多线程支持,因此这种I / O模型已经变得非常可行 . 多线程允许高I / O并发性,使其适用于短期运行和长期运行的阻塞I / O工作负载 . 程序员更有可能引入并发错误,但幸运的是,大多数Web框架的设计方式仍然非常不可能 . 但有一点需要注意的是,由于使用了全局解释器锁(GIL),即使有多个线程,MRI Ruby解释器也无法利用多个CPU核心 . 您可以通过使用多个多线程进程来解决此问题,因为每个进程都可以利用CPU核心 . JRuby和Rubinius没有GIL,因此他们可以在一个进程中充分利用多个核心 .

    • Hybrid multi-threaded multi-process. 主要由Phusion Passenger Enterprise 4及更高版本实施 . 您可以轻松地在单线程多进程,纯多线程或甚至多个进程之间切换,每个进程都有多个线程 . 这个模型给出了两全其美 .

    • Evented. 此模型与前面提到的模型完全不同 . 它允许非常高的I / O并发性,因此非常适合长时间运行的阻塞I / O工作负载 . 要利用它,需要来自应用程序和框架的明确支持 . 但是,像Rails和Sinatra这样的所有主要框架都不支持事件代码 . 这就是为什么在实践中,一个瘦进程仍然无法一次处理多个请求,使其有效地表现与单线程多进程模型相同 . 有一些专门的框架可以利用事件I / O,例如Cramp .

    最近在Phusion博客上发布了一篇文章,关于根据您的工作负载优化调整进程和线程的数量 . 见Tuning Phusion Passenger's concurrency settings .

    卡皮斯特拉诺

    Capistrano是完全不同的东西 . 在前面的所有部分中,“部署”是指在应用程序服务器中启动Ruby应用程序的行为,以便访问者可以访问它,但在此之前,通常需要做一些准备工作,例如:

    • 将Ruby应用程序的代码和文件上传到服务器计算机 .

    • 安装应用所依赖的库 .

    • 设置或迁移数据库 .

    • 启动和停止您的应用可能依赖的任何守护进程,例如Sidekiq / Resque worker或其他任何守护进程 .

    • 在设置应用程序时需要完成的任何其他事情 .

    在Capistrano的背景下,“部署”指的是做所有这些准备工作 . Capistrano不是应用程序服务器 . 相反,它是一个自动完成所有准备工作的工具 . 您告诉Capistrano您的服务器在哪里以及每次部署新版本的应用程序时都需要运行哪些命令,Capistrano将负责将Rails应用程序上传到服务器并运行您指定的命令 .

    Capistrano始终与应用程序服务器结合使用 . 它不会取代应用程序服务器 . 反之亦然,应用服务器不能取代Capistrano,它们可以与Capistrano结合使用 .

    当然你不必使用Capistrano . 如果您希望使用FTP上传Ruby应用程序并且每次都手动运行相同的命令步骤,那么您可以这样做 . 其他人厌倦了,所以他们自动化了Capistrano的这些步骤 .

相关问题