Ruby on Rails服务器选项
为我的Ruby on Rails应用程序设置开发服务器的整个问题让我感到困惑。 有WEBrick,Mongrel,Passenger,Apache,Nginx等等,我相信我并不是很了解他们扮演的angular色。
我开始使用WEBrick,现在我使用Mongrel进行开发。 这些服务器是独立的,还是坐在Apache面前?
我已经阅读了关于Passenger的内容,我不太清楚它是什么,网站上说“能够轻松部署Ruby web应用程序”,它是否取代了Mongrel? 它是否像Capistrano,也部署Web应用程序?
考虑到我想testingSSL,我相信这不是由杂种支持,什么是最好的开发服务器设置?
谢谢
根据上下文,“部署”这个词可以有两个含义。 你也混淆了Apache / Nginx的angular色与其他组件的angular色。
历史性的注解:本文最初是在2010年11月6日写的,当时Ruby应用服务器的生态系统是有限的。 我已经在2013年3月15日更新了这篇文章,其中包括生态系统中的所有最新更新。
免责声明 :我是Phusion Passenger(应用程序服务器之一)的作者之一。
Apache与Nginx
他们都是networking服务器。 他们可以提供静态文件,但是 – 使用正确的模块 – 还可以提供dynamicnetworking应用程序,例如用PHP编写的应用程序。 Apache更stream行,function更多,Nginx更小更快,function更less。
Apache和Nginx都不能直接为Ruby Web应用程序提供服务,因此您需要将Apache / Nginx与某种附加组件(稍后介绍)结合使用。
Apache和Nginx也可以作为反向代理,这意味着他们可以接收一个传入的HTTP请求,并将其转发到另一个服务器,这也可以说HTTP。 当该服务器响应HTTP响应时,Apache / Nginx会将响应转发回客户端; 您将在稍后了解为什么这是相关的。
Mongrel和其他生产应用程序服务器vs WEBrick
Mongrel是Ruby的“应用程序服务器”:具体而言,这意味着Mongrel是一个应用程序:
- 在你自己的进程空间中加载你的Ruby应用程序。
- 设置一个TCP套接字,允许它与外部世界(例如互联网)进行通信。 Mongrel在此套接字上侦听HTTP请求,并将请求数据传递给Ruby Web应用程序。
- Ruby web应用程序然后返回一个对象,该对象描述了HTTP响应应该是什么样子,Mongrel负责将其转换为实际的HTTP响应(实际的字节)并通过套接字将其发回。
然而,杂种是相当过时的,现在不再维护。 较新的替代应用程序服务器是:
- Phusion乘客
- 独angular兽
- 瘦
- 美洲狮
- 特立尼达(仅限JRuby)
- TorqueBox(仅JRuby)
我会在后面介绍他们,并描述他们与Mongrel之间的不同之处。
WEBrick和Mongrel一样,但是区别在于:
- WEBrick不适合生产,不像我之前提到的其他一切。 WEBrick完全是用Ruby编写的。 Mongrel(和大多数其他Ruby应用程序服务器)是Ruby的一部分,也是C的一部分(主要是Ruby),但是它的HTTPparsing器是用C语言编写的。
- WEBrick速度较慢且不太健壮。 它有一些已知的内存泄漏和一些已知的HTTPparsing问题。
- 在开发过程中,WEBrick通常只用作默认服务器,因为默认情况下,WEBrick包含在Ruby中。 Mongrel和其他应用程序服务器需要分开安装。 不build议在生产环境中使用WEBrick,但由于某些原因,Herokuselect了WEBrick作为其默认服务器。 他们以前使用Thin,所以我不知道他们为什么切换到WEBrick。
应用服务器和世界
所有当前的Ruby应用程序服务器都会使用HTTP,但是有些应用程序服务器可能会直接暴露在80端口的互联网上,而另一些则可能不会。
- 可以直接暴露在互联网上的应用服务器:Phusion Passenger,Rainbows
- 应用程序服务器,可能不直接暴露在互联网上:杂种,独angular兽,瘦,彪马。 这些应用程序服务器必须放在像Apache和Nginx这样的反向代理Web服务器之后 。
- 我不太了解特立尼达和TorqueBox,所以我省略了它们。
为什么必须将一些应用程序服务器放在反向代理之后?
- 一些应用程序服务器只能同时处理1个请求,每个进程。 如果您想要同时处理2个请求,则需要运行多个应用服务器实例,每个服务器服务于相同的Ruby应用程序。 这组应用程序服务器进程称为应用程序服务器群集 (因此名称为Mongrel群集,瘦群集等)。 然后,您必须设置Apache或Nginx以将代理转换为此群集。 Apache / Nginx将负责在集群中的实例之间分配请求(更多关于“I / O并发模型”部分的内容)。
- Web服务器可以缓冲请求和响应,保护应用程序服务器免受“慢速客户端”的影响 – HTTP客户端不能很快发送或接受数据。 您不希望您的应用程序服务器在等待客户端发送完整请求或接收完整响应时不做任何操作,因为在此期间,应用程序服务器可能无法执行其他任何操作。 Apache和Nginx同时做很多事情是非常好的,因为它们是multithreading的或者是偶数的。
- 大多数应用程序服务器可以提供静态文件,但不是特别擅长。 Apache和Nginx可以做得更快。
- 人们通常将Apache / Nginx设置为直接提供静态文件,但将不与静态文件相对应的请求转发给应用服务器,这是很好的安全措施。 Apache和Nginx是非常成熟的,可以屏蔽应用程序服务器(可能是恶意)损坏的请求。
为什么一些应用服务器可以直接暴露在互联网上?
- Phusion Passenger与所有其他应用服务器是完全不同的。 它的独特之处在于它集成到了Web服务器中。
- “彩虹”作者公开表示,将其直接暴露给互联网是安全的。 作者相当肯定,在HTTPparsing器(和类似的)中没有漏洞。 尽pipe如此,作者没有提供保证,并表示使用是在自己的风险。
比较应用服务器
在本节中,我将比较我提到的大多数应用程序服务器,但不是Phusion Passenger。 Phusion Passenger与其他人截然不同,我给了它一个专门的部分。 我也省略了Trinidad和TorqueBox,因为我不太了解它们,但是如果您使用JRuby,它们只是相关的。
- 杂种是相当的骨头。 如前所述,Mongrel纯粹是单线程的多进程,所以它只在群集中有用。 没有进程监视:如果群集中的进程崩溃(例如,由于应用程序中的错误),那么需要手动重新启动。 人们倾向于使用外部过程监控工具,如Monit和上帝。
- 独angular兽是Mongrel的一个分支。 它支持有限的进程监视:如果进程崩溃,主进程将自动重启进程。 它可以使所有进程在单个共享套接字上进行监听,而不是为每个进程单独分配一个套接字。 这简化了反向代理configuration。 像Mongrel一样,它纯粹是单线程的多进程。
- Thin通过使用EventMachine库来使用均衡的I / O模型。 除了使用Mongrel HTTPparsing器,它不以任何方式基于Mongrel。 它的集群模式没有进程监视,所以你需要监视崩溃等。没有独angular兽共享套接字,所以每个进程侦听自己的套接字。 从理论上讲,Thin的I / O模型允许高并发性,但在Thin用于大多数实际情况下,一个Thin进程只能处理1个并发请求,因此您仍然需要一个集群。 更多关于“I / O并发模型”部分的这个特殊的属性。
- Puma也是从Mongrel中分出来的,但与Unicorn不同,Puma被devise为纯粹的multithreading。 因此目前没有内置的集群支持。 您需要特别注意确保您可以使用多个内核(更多关于“I / O并发模型”部分的内容)。
- Rainbows通过使用不同的库支持多个并发模型。
Phusion乘客
Phusion Passenger的工作方式与其他所有工作方式都大相径庭。 Phusion Passenger直接集成到Apache或Nginx中,所以可以与Apache的mod_php进行比较。 就像mod_php允许Apache为PHP应用程序提供服务一样,几乎神奇地,Phusion Passenger允许Apache(也包括Nginx!)几乎神奇地为Ruby应用程序提供服务。 Phusion Passenger的目标是让尽可能less的麻烦的一切正常工作(tm)。
而不是为你的应用启动一个进程或者集群,并且configurationApache / Nginx为Phusion Passenger提供静态文件和/或反向代理请求到进程/集群,你只需要:
- 你编辑Web服务器configuration文件,并指定你的Ruby应用程序的“公共”目录的位置。
- 没有第二步。
所有configuration都在Web服务器configuration文件中完成。 Phusion乘客自动化几乎所有的东西。 不需要启动集群并pipe理进程。 启动/停止进程,在崩溃时重启进程等 – 全部自动化。 与其他应用程序服务器相比,Phusion Passenger的移动部件less得多。 这种易用性是人们使用Phusion Passenger的主要原因之一。
与其他应用程序服务器不同,Phusion Passenger主要使用C ++编写,因此速度非常快。
另外还有一个Phusion Passenger的Enterprise版本 ,它具有更多的function,如自动滚动重启,multithreading支持,部署错误抵抗等等。
由于上述原因,Phusion Passenger是目前最stream行的Ruby应用程序服务器,为超过15万个网站提供支持,其中包括纽约时报,皮克斯,Airbnb等大型网站。
Phusion Passenger vs其他应用程序服务器
Phusion Passenger提供了更多的function,并提供了许多优于其他应用程序服务器的优势,例如:
- 根据stream量dynamic调整进程数。 我们在资源受限的服务器上运行了大量的Rails应用程序,这些应用程序不是面向公众的,而且我们组织中的人员一天最多只能使用几次。 比如Gitlab,Redmine等。Phusion Passenger可以在不使用的时候减less这些进程,并在使用时将其旋转起来,从而为更重要的应用程序提供更多的资源。 与其他应用程序服务器一起,您的所有进程都处于打开状态。
- 某些应用程序服务器在某些工作负载上并不擅长devise。 例如Unicorn专为快速运行的请求而devise:请参阅Unicorn网站部分“在某些情况下更糟糕”。
独angular兽不擅长的工作量是:
- stream式工作负载(例如Rails 4直播或Rails 4模板stream式传输)。
- 应用程序执行HTTP API调用的工作负载。
Phusion Passenger Enterprise 4或更高版本中的混合I / O模型使其成为这类工作负载的理想select。
- 其他应用程序服务器要求用户每个应用程序至less运行一个实例。 相比之下,Phusion Passenger在单一实例中支持多个应用程序。 这大大减less了pipe理开销。
- 自动用户切换,方便的安全function。
- Phusion Passenger支持许多MRI Ruby,JRuby和Rubinius。 杂种,独angular兽和瘦只支持MRI。 彪马也支持所有3。
- Phusion Passenger实际上支持的不仅仅是Ruby! 它也支持Python的WSGI,所以它也可以运行Django和Flask应用程序。 事实上,Phusion Passenger正朝着成为一个多语种服务器的方向发展。 待办事项列表上的Node.js支持。
- 带外垃圾收集。 Phusion Passenger可以在正常的请求/响应周期之外运行Ruby垃圾收集器,这可能会将请求时间缩短数百毫秒。 独angular兽也有类似的function,但是Phusion Passenger的版本更加灵活,因为1)它不限于GC,可以用于任意工作。 2)Phusion Passenger的版本适用于multithreading应用程序,而Unicorn则不适用。
- 自动滚动重启。 Unicorn和其他服务器上的滚动重新启动需要一些脚本工作。 Phusion乘客企业为您完全自动化这种方式。
还有更多的function和优势,但名单真的很长。 您应该参考全面的Phusion乘客手册( Apache版本 , Nginx版本 )或Phusion乘客网站的信息。
I / O并发模型
- 单线程多进程。 传统上,这是Ruby应用服务器最stream行的I / O模型,部分原因在于Ruby生态系统中的multithreading支持非常糟糕。 每个进程一次只能处理1个请求。 Web服务器在进程之间负载平衡。 这个模型非常强大,程序员很less有机会引入并发错误。 但是,它的I / O并发性非常有限(受到进程数量的限制)。 此模型非常适合快速,短时间运行的工作负载。 对于缓慢,长时间运行的阻塞I / O工作负载,例如涉及调用HTTP API的工作负载,这是非常不合适的。
- 纯粹是multithreading的。 现在,Ruby生态系统具有出色的multithreading支持,所以这个I / O模型变得非常可行。 multithreading允许高I / O并发性,使其适用于短时间运行和长时间运行的阻塞I / O工作负载。 程序员更可能引入并发错误,但幸运的是,大多数Web框架的devise方式仍然不太可能。 但是需要注意的是,由于使用了全局解释器锁(GIL),MRI Ruby解释器即使在有多个线程时也不能利用多个CPU内核。 您可以通过使用多个multithreading进程来解决此问题,因为每个进程都可以利用CPU内核。 JRuby和Rubinius没有GIL,所以他们可以在一个进程中充分利用多个内核。
- 混合multithreading多进程。 主要由Phusion乘客企业4及以后实施。 您可以轻松地在单线程多进程,纯multithreading或甚至多个进程之间切换,每个线程都有多个线程。 这个模型给了两全其美。
- 事件触发。 这个模型与前面提到的模型完全不同。 它允许非常高的I / O并发性,因此非常适合长时间运行的阻塞I / O工作负载。 为了利用它,需要来自应用程序和框架的明确支持。 但是像Rails和Sinatra这样的主要框架都不支持代码。 这就是为什么在实践中,精简stream程仍然无法同时处理多于一个的请求,使其与单线程多进程模型的行为一样有效。 有专门的框架可以利用均匀的I / O,比如Cramp。
最近在Phusion博客上发布了一篇关于优化调整工作负载的进程和线程数量的文章。 请参阅调整Phusion Passenger的并发设置 。
Capistrano的
卡皮斯特拉诺是完全不同的东西。 在前面的部分中,“部署”是指在应用程序服务器中启动Ruby应用程序的行为,以便访问者能够访问它,但在此之前,通常需要做一些准备工作,例如:
- 将Ruby应用程序的代码和file upload到服务器机器。
- 安装你的应用程序依赖的库。
- 设置或迁移数据库。
- 开始和停止你的应用程序可能依赖的任何守护进程,如Sidekiq / Resque workers或其他。
- 当您设置您的应用程序时,需要做的任何其他事情。
在Capistrano的情况下,“部署”是指做所有这些准备工作。 Capistrano不是应用程序服务器。 相反,它是一个自动化所有准备工作的工具。 您告诉Capistrano您的服务器在哪里,每次部署新版本的应用程序时需要运行哪些命令,Capistrano将负责将Rails应用程序上传到服务器,并运行您指定的命令。
Capistrano总是与应用程序服务器结合使用。 它不会取代应用程序服务器。 反之亦然,应用程序服务器不会取代Capistrano,它们可以与Capistrano结合使用。
当然你不必使用Capistrano。 如果你喜欢用FTP上传你的Ruby应用程序,并且每次都手动运行相同的命令步骤,那么你可以这样做。 其他人厌倦了,所以他们在Capistrano自动化这些步骤。