Ruby on Rails 服务器选项

发布于 2024-09-30 17:49:55 字数 360 浏览 1 评论 0原文

为我的 Ruby on Rails 应用程序设置开发服务器的整个问题让我感到困惑。我确信有 WEBrick、Mongrel、Passenger、Apache、Nginx 等等,但我不太了解它们所扮演的不同角色。

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

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

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

谢谢

The whole issue of setting up a development server for my Ruby on Rails application confuses me. There are WEBrick, Mongrel, Passenger, Apache, Nginx and many more I am sure, and I don't really understand the different roles they play.

I started off using WEBrick, and now I use Mongrel for development. Are these servers stand-alone, or do they sit in front of Apache?

I have read about Passenger and I don't really understand what it is, the site says "makes deployment of Ruby web applications a breeze", does it replace Mongrel? Is it like Capistrano, which also deploys web applications?

Bearing in mind I would like to test SSL, and I believe that's not supported by mongrel, what is the best development server setup?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我喜欢麦丽素 2024-10-07 17:49:55

根据上下文,“部署”一词可以有两种含义。您还将 Apache/Nginx 的角色与其他组件的角色混淆了。

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

免责声明:我是 Phusion Passenger(应用程序服务器之一)的作者之一。

Apache 与 Nginx

它们都是 Web 服务器。它们可以提供静态文件,但通过正确的模块,也可以提供动态 Web 应用程序,例如用 PHP 编写的应用程序。 Apache 更流行,功能更多,Nginx 更小、更快,功能更少。

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

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

Mongrel 和其他生产应用程序服务器与 WEBrick

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

  1. 在其自己的进程空间内加载您的 Ruby 应用程序。
  2. 建立一个TCP套接字,允许其与外界(例如互联网)进行通信。
    Mongrel 侦听此套接字上的 HTTP 请求并将请求数据传递到 Ruby Web 应用程序。
  3. 然后,Ruby Web 应用程序返回一个对象,该对象描述了 HTTP 响应应该是什么样子,Mongrel 负责将其转换为实际的 HTTP 响应(实际字节)并通过套接字将其发送回。

然而 Mongrel 已经相当过时了,现在它不再被维护了。较新的替代应用程序服务器有:

  • Phusion Passenger
  • Unicorn
  • Thin
  • Puma
  • Trinidad(仅限 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
  • 可能不会直接暴露在互联网上的应用服务器:Mongrel、Unicorn、Thin、Puma。这些应用程序服务器必须放置在 Apache 和 Nginx 等反向代理 Web 服务器后面。
  • 我对 Trinidad 和 TorqueBox 不太了解,所以我省略了它们。

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

  • 某些应用程序服务器每个进程只能同时处理 1 个请求。如果您想同时处理 2 个请求,则需要运行多个应用程序服务器实例,每个实例服务于同一个 Ruby 应用程序。这组应用服务器进程称为应用服务器集群(因此称为 Mongrel Cluster、Thin Cluster 等)。然后,您必须设置 Apache 或 Nginx 以反向代理到该集群。 Apache/Nginx 将负责在集群中的实例之间分配请求(更多信息请参见“I/O 并发模型”部分)。
  • Web 服务器可以缓冲请求和响应,从而保护应用程序服务器免受“慢速客户端”(不能很快发送或接受数据的 HTTP 客户端)的影响。您不希望您的应用程序服务器在等待客户端发送完整请求或接收完整响应时不执行任何操作,因为在此期间应用程序服务器可能无法执行任何其他操作。 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 并发模型”部分。
  • Puma 也是从 Mongrel 分叉出来的,但与 Unicorn 不同的是,Puma 被设计为纯粹的多线程。因此,目前没有内置集群支持。您需要特别小心,以确保可以利用多个内核(更多信息请参见“I/O 并发模型”部分)。
  • 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 来为进程/集群提供静态文件和/或反向代理请求,您只需:

  1. 编辑 Web 服务器配置文件并指定位置您的 Ruby 应用程序的“public”目录。
  2. 没有步骤 2。

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

与其他应用服务器不同的是,Phusion Passenger 主要用 C++ 编写,因此速度非常快。

还有 Phusion Passenger 的企业版,具有更多功能,例如自动滚动重启、多线程支持、部署 Phusion

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

其他应用服务器比较

Passenger 与Phusion 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。 Puma 还支持所有 3 个语言。Phusion
  • Passenger 实际上不仅仅支持 Ruby!它还支持 Python WSGI,因此它还可以运行 Django 和 Flask 应用程序。事实上,Phusion Passenger 正在朝着成为多语言服务器的方向发展。待办事项列表中的 Node.js 支持。
  • 带外垃圾收集。 Phusion Passenger 可以在正常请求/响应周期之外运行 Ruby 垃圾收集器,从而可能将请求时间减少数百毫秒。 Unicorn 也有类似的功能,但 Phusion Passenger 的版本更灵活,因为
    1)它不限于GC,可以用于任意工作。
    2) Phusion Passenger 的版本可以很好地与多线程应用程序配合使用,而 Unicorn 的则不能。
  • 自动滚动重新启动。 Unicorn 和其他服务器上的滚动重新启动需要一些脚本工作。 Phusion Passenger Enterprise 为您完全自动化这种方式。

还有更多的功能和优点,但列表确实很长。您应该参考全面的 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 Passenger Enterprise 4 及更高版本实现。您可以轻松地在单线程多进程、纯多线程甚至多个进程(每个进程具有多个线程)之间切换。该模型提供了两全其美的优点。
  • 事件。此模型与前面提到的模型完全不同。它允许非常高的 I/O 并发性,因此非常适合长时间运行的阻塞 I/O 工作负载。要利用它,需要应用程序和框架的明确支持。然而,所有主要框架(如 Rails 和 Sinatra)都不支持事件代码。这就是为什么在实践中瘦进程仍然无法一次处理超过 1 个请求,使其实际上与单线程多进程模型的行为相同。有一些专门的框架可以利用事件 I/O,例如 Cramp。

最近在 Phusion 博客上发布了一篇文章,内容涉及根据工作负载优化调整进程和线程的数量。请参阅调整 Phusion Passenger 的并发设置

卡皮斯特拉诺

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

  • : Ruby 应用程序的代码和文件传输到服务器计算机。
  • 安装您的应用程序依赖的库。
  • 设置或迁移数据库。
  • 启动和停止您的应用程序可能依赖的任何守护进程,例如 Sidekiq/Resque 工作线程或其他进程。
  • 设置应用程序时需要完成的任何其他事情。

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

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

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

The word "deployment" can have two meanings depending on the context. You are also confusing the roles of Apache/Nginx with the roles of other components.

Historic note: This article was originally written on November 6, 2010, when the Ruby app server ecosystem was limited. I've updated this article on March 15 2013 with all the latest updates in the ecosystem.

Disclaimer: I am one of the authors of Phusion Passenger, one of the app servers.

Apache vs Nginx

They're both web servers. They can serve static files but - with the right modules - can also serve dynamic web apps e.g. those written in PHP. Apache is more popular and has more features, Nginx is smaller and faster and has less features.

Neither Apache nor Nginx can serve Ruby web apps out-of-the-box, to do that you need to use Apache/Nginx in combination with some kind of add-on, described later.

Apache and Nginx can also act as reverse proxies, meaning that they can take an incoming HTTP request and forward it to another server, which also speaks HTTP. When that server responds with an HTTP response, Apache/Nginx will forward the response back to the client; You will learn later why this is relevant.

Mongrel and other production app servers vs WEBrick

Mongrel is a Ruby "application server": In concrete terms this means that Mongrel is an application which:

  1. Loads your Ruby app inside its own process space.
  2. Sets up a TCP socket, allowing it to communicate with the outside world (e.g. the Internet).
    Mongrel listens for HTTP requests on this socket and passes the request data to the Ruby web app.
  3. The Ruby web app then returns an object, which describes what the HTTP response should look like, and Mongrel takes care of converting it to an actual HTTP response (the actual bytes) and sends it back over the socket.

However Mongrel is quite dated, nowadays it is no longer maintained. Newer alternative application servers are:

  • Phusion Passenger
  • Unicorn
  • Thin
  • Puma
  • Trinidad (JRuby only)
  • TorqueBox (JRuby only)

I'll cover them later and describe how they differ from each other and from Mongrel.

WEBrick does the same thing as Mongrel, but the differences are:

  • WEBrick is not fit for production, unlike everything else that I mentioned before. WEBrick is written entirely in Ruby. Mongrel (and most other Ruby app servers) is part Ruby and part C (Mostly Ruby), but its HTTP parser is written in C for performance.
  • WEBrick is slower and less robust. It has some known memory leaks and some known HTTP parsing problems.
  • WEBrick is usually only used as the default server during development because WEBrick is included in Ruby by default. Mongrel and other app servers needs to be installed separately. It's not recommended to use WEBrick in production environments, though for some reason Heroku chose WEBrick as its default server. They were using Thin before, so I have no idea why they switched to WEBrick.

The app server and the world

All current Ruby app servers speak HTTP, however some app servers may be directly exposed to the Internet on port 80, while others may not.

  • App servers that can be directly exposed to the Internet: Phusion Passenger, Rainbows
  • App servers that may not be directly exposed to the Internet: Mongrel, Unicorn, Thin, Puma. These app servers must be put behind a reverse proxy web server like Apache and Nginx.
  • I don't know enough about Trinidad and TorqueBox, so I've omitted them.

Why must some app servers be put behind a reverse proxy?

  • Some app servers can only handle 1 request concurrently, per process. If you want to handle 2 requests concurrently you need to run multiple app server instances, each serving the same Ruby app. This set of app server processes is called an app server cluster (hence the name Mongrel Cluster, Thin Cluster, etc). You must then setup Apache or Nginx to reverse proxy to this cluster. Apache/Nginx will take care of distributing requests between the instances in the cluster (More on this in section "I/O concurrency models").
  • The web server can buffer requests and responses, protecting the app server from "slow clients" - HTTP clients that don't send or accept data very quickly. You don't want your app server to do nothing while waiting for the client to send the full request or to receive the full response, because during that time the app server may not be able to do anything else. Apache and Nginx are very good at doing many things at the same time because they're either multithreaded or evented.
  • Most app servers can serve static files, but are not particularly good at it. Apache and Nginx can do it faster.
  • People typically set up Apache/Nginx to serve static files directly, but forward requests that don't correspond with static files to the app server, it's good security practice. Apache and Nginx are very mature and can shield the app server from (perhaps maliciously) corrupted requests.

Why can some app servers be directly exposed to the Internet?

  • Phusion Passenger is a very different beast from all the other app servers. One of its unique features is that it integrates into the web server.
  • The Rainbows author publicly stated that it's safe to directly expose it to the Internet. The author is fairly sure that there are no vulnerabilities in the HTTP parser (and similar). Still, the author provides no warranty and says that usage is at own risk.

Application servers compared

In this section I'll compare most application servers I've mentioned, but not Phusion Passenger. Phusion Passenger is such a different beast from the rest that I've given it a dedicated section. I've also omitted Trinidad and TorqueBox because I do not know them well enough, but they're only relevant anyway if you use JRuby.

  • Mongrel was pretty bare bones. As mentioned earlier, Mongrel is purely single-threaded multi-process, so it is only useful in a cluster. There is no process monitoring: if a process in the cluster crashes (e.g. because of a bug in the app) then it needs to be manually restarted. People tend to use external process monitoring tools such as Monit and God.
  • Unicorn is a fork of Mongrel. It supports limited process monitoring: if a process crashes it is automatically restarted by the master process. It can make all processes listen on a single shared socket, instead of a separate socket for each process. This simplifies reverse proxy configuration. Like Mongrel, it is purely single-threaded multi-process.
  • Thin uses the evented I/O model by utilizing the EventMachine library. Other than using the Mongrel HTTP parser, it is not based on Mongrel in any way. Its cluster mode has no process monitoring so you need to monitor crashes etc. There is no Unicorn-like shared socket, so each process listens on its own socket. In theory, Thin's I/O model allows high concurrency, but in most practical situations that Thin is used for, one Thin process can only handle 1 concurrent request, so you still need a cluster. More about this peculiar property in section "I/O concurrency models".
  • Puma was also forked from Mongrel, but unlike Unicorn, Puma is designed to be purely multi-threaded. There is therefore currently no builtin cluster support. You need to take special care to ensure that you can utilize multiple cores (More about this in section "I/O concurrency models").
  • Rainbows supports multiple concurrency models through the use of different libraries.

Phusion Passenger

Phusion Passenger works very differently from all the other ones. Phusion Passenger integrates directly into Apache or Nginx, and so can be compared to mod_php for Apache. Just like mod_php allows Apache to serve PHP apps, almost magically, Phusion Passenger allows Apache (and also Nginx!) to serve Ruby apps, almost magically. Phusion Passenger's goal is to make everything Just Work(tm) with as little hassle as possible.

Instead of starting a process or cluster for your app, and configuring Apache/Nginx to serve static files and/or reverse proxying requests to the process/cluster with Phusion Passenger you only need to:

  1. You edit the web server config file and specify the location of your Ruby app's 'public' directory.
  2. There is no step 2.

All configuration is done within the web server config file. Phusion Passenger automates pretty much everything. There is no need to start a cluster and manage processes. Starting/stopping processes, restarting them when they crash, etc. - all automated. Compared to other app servers, Phusion Passenger has far fewer moving parts. This ease of use is one of the primary reasons why people use Phusion Passenger.

Also unlike other app servers, Phusion Passenger is primarily written in C++, making it very fast.

There's also an Enterprise variant of Phusion Passenger with even more features, such as automated rolling restarts, multithreading support, deployment error resistance, etc.

For the above reasons, Phusion Passenger is currently the most popular Ruby app server, powering over 150,000 websites, including large ones such as New York Times, Pixar, Airbnb, etc.

Phusion Passenger vs other app servers

Phusion Passenger provides a lot more features and provides many advantages over other app servers, such as:

  • Dynamically adjusting the number of processes based on traffic. We run a ton of Rails apps on our resource-constrainted server that are not public-facing, and that people in our organization only use at most a few times a day. Things like Gitlab, Redmine, etc. Phusion Passenger can spin down those processes when they're not used, and spinning them up when they're used, allowing more resources to be available for more important apps. With other app servers, all your processes are turned on all the time.
  • Some app servers are not good at certain workloads, by design. For example Unicorn is designed for fast-running requests only: See the Unicorn website section "Just Worse in Some Cases".

Workloads that Unicorn is not good at are:

  • Streaming workloads (e.g. Rails 4 live streaming or Rails 4 template streaming).
  • Workloads in which the app performs HTTP API calls.

The hybrid I/O model in Phusion Passenger Enterprise 4 or later makes it an excellent choice for these kinds of workloads.

  • Other app servers require the user to run at least one instance per application. By contrast, Phusion Passenger supports multiple applications in a single instance. This greatly reduces administration overhead.
  • Automatic user switching, a convenient security feature.
  • Phusion Passenger supports many MRI Ruby, JRuby and Rubinius. Mongrel, Unicorn and Thin only support MRI. Puma also supports all 3.
  • Phusion Passenger actually supports more than just Ruby! It also supports Python WSGI, so it can for example also run Django and Flask apps. In fact Phusion Passenger is moving into the direction of becoming a polyglot server. Node.js support on the todo list.
  • Out-of-band garbage collection. Phusion Passenger can run the Ruby garbage collector outside the normal request/response cycle, potentially reducing request times by hundreds of milliseconds. Unicorn also has a similar feature, but Phusion Passenger's version is more flexible because
    1) it's not limited to GC and can be used for arbitrary work.
    2) Phusion Passenger's version works well with multithreaded apps, while Unicorn's does not.
  • Automated rolling restarts. Rolling restarts on Unicorn and other servers require some scripting work. Phusion Passenger Enterprise completely automates this way for you.

There are more features and advantages, but the list is really long. You should refer to the comprehensive Phusion Passenger manual (Apache version, Nginx version) or the Phusion Passenger website for information.

I/O concurrency models

  • Single-threaded multi-process. This is traditionally the most popular I/O model for Ruby app servers, partially because multithreading support in the Ruby ecosystem was very bad. Each process can handle exactly 1 request at a time. The web server load balances between processes. This model is very robust and there is little chance for the programmer to introduce concurrency bugs. However, its I/O concurrency is extremely limited (limited by the number of processes). This model is very suitable for fast, short-running workloads. It is very unsuitable for slow, long-running blocking I/O workloads, e.g. workloads involving the calling of HTTP APIs.
  • Purely multi-threaded. Nowadays the Ruby ecosystem has excellent multithreading support, so this I/O model has become very viable. Multithreading allows high I/O concurrency, making it suitable for both short-running and long-running blocking I/O workloads. The programmer is more likely to introduce concurrency bugs, but luckily most web frameworks are designed in such a way that this is still very unlikely. One thing to note however is that the MRI Ruby interpreter cannot leverage multiple CPU cores even when there are multiple threads, due to the use of the Global Interpreter Lock (GIL). You can work around this by using multiple multi-threaded processes, because each process can leverage a CPU core. JRuby and Rubinius have no GIL, so they can fully leverage multiple cores in a single process.
  • Hybrid multi-threaded multi-process. Primarily implemented by Phusion Passenger Enterprise 4 and later. You can easily switch between single-threaded multi-process, purely multithreaded, or perhaps even multiple processes each with multiple threads. This model gives the best of both worlds.
  • Evented. This model is completely different from the previously mentioned model. It allows very high I/O concurrency and is therefore excellent for long-running blocking I/O workloads. To utilize it, explicit support from the application and the framework is required. However all the major frameworks like Rails and Sinatra do not support evented code. This is why in practice a Thin process still cannot handle more than 1 request at a time, making it effectively behave the same as the single-threaded multi-process model. There are specialized frameworks that can take advantage of evented I/O, such as Cramp.

An article was recently posted on the Phusion blog about optimally tuning the number of processes and threads given your workload. See Tuning Phusion Passenger's concurrency settings.

Capistrano

Capistrano is something completely different. In all the previous sections, "deployment" refers to the act of starting your Ruby app in an application server, so that it becomes accessible to visitors, but before that can happen one typically needs to do some preparation work, such as:

  • Uploading the Ruby app's code and files to the server machine.
  • Installing libraries that your app depends on.
  • Setting up or migrating the database.
  • Starting and stopping any daemons that your app might rely on, such as Sidekiq/Resque workers or whatever.
  • Any other things that need to be done when you're setting up your application.

In the context of Capistrano, "deployment" refers to doing all this preparation work. Capistrano is not an application server. Instead, it is a tool for automating all that preparation work. You tell Capistrano where your server is and which commands need to be run every time you deploy a new version of your app, and Capistrano will take care of uploading the Rails app to the server for you and running the commands you specified.

Capistrano is always used in combination with an application server. It does not replace application servers. Vice-versa, application servers do not replace Capistrano, they can be used in combination with Capistrano.

Of course you don't have to use Capistrano. If you prefer to upload your Ruby app with FTP and manually running the same steps of commands every time, then you can do that. Other people got tired of it, so they automate those steps in Capistrano.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文