取决于上下文,“部署”一词可以有两种含义。您还将混淆Apache / Nginx的角色与其他组件的角色。
历史注释:本文最初写于2010年11月6日,当时Ruby应用服务器生态系统受到限制。我已于2013年3月15日使用生态系统中的所有最新更新更新了本文。
免责声明:我是Phusion Passenger(应用程序服务器之一)的作者之一。
阿帕奇vs Nginx
它们都是Web服务器。它们可以提供静态文件,但是-通过正确的模块-还可以提供动态Web应用程序,例如用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响应(实际的字节)并通过套接字发送回去。
但是,Mongrel已过时,如今已不再维护。较新的替代应用服务器是:
- Phusion乘客
- 独角兽
- 瘦
- 彪马
- 特立尼达(仅JRuby)
- TorqueBox(仅JRuby)
稍后我将介绍它们,并描述它们之间以及与Mongrel之间的区别。
WEBrick与Mongrel的作用相同,但区别在于:
- 与我之前提到的所有其他内容不同,WEBrick不适合生产。WEBrick完全用Ruby编写。Mongrel(和大多数其他Ruby应用程序服务器)是Ruby的一部分,而C是大多数Ruby的一部分,但是出于性能考虑,其HTTP解析器是用C编写的。
- WEBrick较慢且较不健壮。它具有一些已知的内存泄漏和一些已知的HTTP解析问题。
- WEBrick通常仅在开发过程中用作默认服务器,因为默认情况下,Ruby中包含WEBrick。Mongrel和其他应用程序服务器需要单独安装。不建议在生产环境中使用WEBrick,尽管出于某些原因,Heroku选择了WEBrick作为其默认服务器。他们以前使用过Thin,所以我不知道为什么他们切换到WEBrick。
应用服务器与世界
当前所有的Ruby应用程序服务器都使用HTTP,但是某些应用程序服务器可能直接通过端口80暴露给Internet,而另一些则可能没有。
- 可以直接暴露给Internet的应用服务器:Phusion Passenger,Rainbows
- 可能不会直接暴露给Internet的应用程序服务器:Mongrel,Unicorn,Thin,Puma。这些应用服务器必须放在反向代理Web服务器(例如Apache和Nginx)后面。
- 我对特立尼达和TorqueBox的了解不够,所以我省略了它们。
为什么必须将某些应用程序服务器置于反向代理之后?
- 某些应用服务器每个进程只能同时处理1个请求。如果要同时处理2个请求,则需要运行多个应用服务器实例,每个实例都服务于同一个Ruby应用。这套应用程序服务器进程称为应用程序服务器集群(因此名称为Mongrel Cluster,Thin Cluster等)。然后,您必须设置Apache或Nginx来反向代理此集群。Apache / Nginx将负责在集群中的实例之间分配请求(有关更多信息,请参见“ I / O并发模型”部分)。
- Web服务器可以缓冲请求和响应,从而保护应用程序服务器免受“慢速客户端”的影响-HTTP客户端不会非常快速地发送或接受数据。您不希望应用服务器在等待客户端发送完整请求或接收完整响应的同时不执行任何操作,因为在此期间,应用服务器可能无法执行其他任何操作。Apache和Nginx非常擅长同时执行许多操作,因为它们是多线程的或有事件的。
- 大多数应用程序服务器可以提供静态文件,但并不是特别擅长。Apache和Nginx可以更快地做到这一点。
- 人们通常将Apache / Nginx设置为直接提供静态文件,但是将与静态文件不对应的请求转发到应用服务器,这是一种很好的安全做法。Apache和Nginx非常成熟,可以保护应用服务器免受(可能是恶意的)损坏的请求的侵害。
为什么某些应用程序服务器可以直接暴露于Internet?
- Phusion Passenger与所有其他应用程序服务器完全不同。它的独特功能之一是将其集成到Web服务器中。
- Rainbows作者公开表示,将其直接暴露于Internet是安全的。作者相当确定HTTP解析器(及类似文件)中没有漏洞。尽管如此,作者仍不提供任何保证,并说使用风险自负。
应用服务器比较
在本节中,我将比较我提到的大多数应用程序服务器,而不是Phusion Passenger。Phusion Passenger与其余的野兽截然不同,我专门为它提供了一个部分。我也省略了Trinidad和TorqueBox,因为我不太了解它们,但是无论如何,只有在使用JRuby时它们才有意义。
- 杂种很裸露。如前所述,Mongrel是纯单线程多进程,因此仅在集群中有用。没有进程监视:如果集群中的进程崩溃(例如,由于应用程序中的错误所致),则需要手动重新启动它。人们倾向于使用外部过程监视工具,例如Monit和God。
- 独角兽是杂种的叉子。它支持有限的进程监视:如果进程崩溃,则主进程会自动将其重新启动。它可以使所有进程在单个共享套接字上侦听,而不是为每个进程使用单独的套接字。这简化了反向代理配置。像Mongrel一样,它是纯单线程多进程。
- Thin通过利用EventMachine库使用事件I / O模型。除了使用Mongrel HTTP解析器外,它完全不基于Mongrel。它的集群模式没有进程监视,因此您需要监视崩溃等。没有类似Unicorn的共享套接字,因此每个进程都在自己的套接字上侦听。理论上,Thin的I / O模型允许高并发性,但是在使用Thin的大多数实际情况下,一个Thin进程只能处理1个并发请求,因此您仍然需要一个集群。在“ I / O并发模型”部分中将详细介绍此特殊属性。
- Puma也是从Mongrel派生出来的,但与Unicorn不同,Puma设计为纯多线程的。因此,当前没有内置的群集支持。您需要格外小心,以确保可以利用多个内核(有关更多信息,请参见“ I / O并发模型”部分)。
- Rainbows通过使用不同的库支持多种并发模型。
Phusion乘客
Phusion Passenger的 工作方式与其他所有方式截然不同。Phusion Passenger直接集成到Apache或Nginx中,因此可以与Apache的mod_php进行比较。就像mod_php允许Apache几乎神奇地为PHP应用程序提供服务一样,Phusion Passenger允许Apache(以及Nginx!)几乎可以为神奇的Ruby应用程序提供服务。Phusion Passenger的目标是使一切正常工作(tm)尽可能少麻烦。
无需为您的应用启动进程或集群,而是配置Apache / Nginx来使用Phusion Passenger提供静态文件和/或向进程/集群的反向代理请求,您只需要:
- 您编辑Web服务器配置文件,并指定Ruby应用程序的“公共”目录的位置。
- 没有步骤2。
所有配置都在Web服务器配置文件中完成。Phusion Passenger几乎可以使所有事情自动化。无需启动集群并管理进程。启动/停止进程,当它们崩溃时重新启动它们,等等-全部自动化。与其他应用程序服务器相比,Phusion Passenger的活动部件少得多。这种易用性是人们使用Phusion客机的主要原因之一。
与其他应用程序服务器不同,Phusion Passenger主要使用C ++编写,因此速度非常快。
还有Phusion Passenger 的Enterprise变体,它具有更多功能,例如自动滚动重启,多线程支持,抗部署错误等。
由于上述原因,Phusion Passenger是目前最受欢迎的Ruby应用服务器,为超过150,000个网站提供了支持,其中包括纽约时报,皮克斯,Airbnb等大型网站。
Phusion Passenger与其他应用程序服务器
与其他应用服务器相比,Phyion Passenger提供了更多功能,并提供了许多优势,例如:
- 根据流量动态调整进程数。我们在资源受限的服务器上运行大量的Rails应用程序,这些应用程序不是面向公众的,并且组织中的人员每天最多只能使用几次。诸如Gitlab,Redmine等之类的东西。Phusion Passenger可以在不使用它们时降低其进程,并在使用它们时加快它们的速度,从而为更多重要的应用程序提供更多资源。与其他应用程序服务器一起,所有进程都始终处于打开状态。
- 根据设计,某些应用程序服务器不能胜任某些工作负载。例如,Unicorn仅设计用于快速运行的请求:请参见Unicorn网站的 “在某些情况下只是更糟”部分。
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。彪马还支持所有3。
- 实际上,Phusion Passenger不仅仅支持Ruby!它还支持Python WSGI,因此它也可以运行Django和Flask应用程序。实际上,Phusion Passenger正在朝着成为多种语言服务器的方向发展。待办事项列表上的Node.js支持。
- 带外垃圾收集。Phusion Passenger可以在正常请求/响应周期之外运行Ruby垃圾收集器,从而有可能减少数百毫秒的请求时间。独角兽也具有类似的功能,但是Phusion Passenger的版本更加灵活,因为1)它不仅限于GC,而且可以用于任意工作。2)Phusion Passenger的版本适用于多线程应用程序,而Unicorn的版本不适用。
- 自动滚动重新启动。在Unicorn和其他服务器上滚动重启需要一些脚本工作。Phusion客运企业完全为您实现了这种自动化。
有更多的功能和优点,但清单确实很长。您应该参考全面的Phusion Passenger手册(Apache版本,Nginx版本)或Phusion Passenger网站以获取信息。
I / O并发模型
- 单线程多进程。传统上,这是Ruby应用服务器最受欢迎的I / O模型,部分原因是Ruby生态系统中的多线程支持非常糟糕。每个进程一次只能处理1个请求。Web服务器在进程之间进行负载平衡。这个模型非常健壮,程序员几乎没有机会引入并发错误。但是,其I / O并发性非常有限(受进程数限制)。该模型非常适合快速,短期运行的工作负载。它非常不适用于缓慢,长时间运行的阻塞I / O工作负载,例如,涉及调用HTTP API的工作负载。
- 纯多线程。如今,Ruby生态系统具有出色的多线程支持,因此该I / O模型变得非常可行。多线程允许高I / O并发性,使其适合短期运行和长期运行的阻塞I / O工作负载。程序员更有可能引入并发错误,但是幸运的是,大多数Web框架的设计方式仍然不太可能。但是要注意的一件事是,由于使用了全局解释器锁(GIL),即使有多个线程,MRI Ruby解释器也无法利用多个CPU内核。您可以通过使用多个多线程进程来解决此问题,因为每个进程都可以利用CPU内核。JRuby和Rubinius没有GIL,因此它们可以在单个过程中充分利用多个内核。
- 混合多线程多进程。主要由Phusion客运企业4及更高版本实施。您可以轻松地在单线程多进程,纯多线程甚至是每个都有多个线程的多个进程之间切换。此模型兼具两全其美的优点。
- 大事记 该模型与前面提到的模型完全不同。它允许很高的I / O并发性,因此非常适合长时间运行的阻塞I / O工作负载。要使用它,需要应用程序和框架的显式支持。但是,所有主要框架(如Rails和Sinatra)都不支持事件代码。这就是为什么在实践中,精简进程仍然不能一次处理多个请求,从而使其行为与单线程多进程模型相同。有专门的框架可以利用事件I / O,例如Cramp。
最近在Phusion博客上发布了一篇文章,介绍了根据您的工作量来优化调整进程和线程的数量。请参阅调整Phusion Passenger的并发设置。
Capistrano
Capistrano是完全不同的东西。在前面的所有部分中,“部署”是指在应用程序服务器中启动Ruby应用程序的操作,以便访问者可以访问它,但是在此之前,通常需要做一些准备工作,例如:
- 将Ruby应用程序的代码和文件上传到服务器计算机。
- 安装您的应用程序依赖的库。
- 设置或迁移数据库。
- 启动和停止您的应用程序可能依赖的所有守护程序,例如Sidekiq / Resque worker或其他。
- 设置应用程序时需要完成的任何其他操作。
在Capistrano的上下文中,“部署”是指完成所有准备工作。Capistrano不是应用程序服务器。相反,它是用于自动化所有准备工作的工具。每次部署新版本的应用程序时,您都告诉Capistrano服务器在哪里以及需要运行哪些命令,Capistrano将负责将Rails应用程序上载到服务器并运行您指定的命令。
Capistrano始终与应用程序服务器结合使用。它不会替换应用程序服务器。反之亦然,应用程序服务器不能代替Capistrano,可以与Capistrano结合使用。
当然你不具备使用Capistrano的。如果您希望通过FTP上传Ruby应用并每次都手动运行相同的命令步骤,则可以这样做。其他人对此感到厌倦,因此他们在Capistrano中自动化了这些步骤。