问题

为我的Ruby on Rails应用程序设置开发服务器的整个问题困惑我.有WEBrick,Mongrel,Passenger,Apache,Nginx和更多我相信,我真的不明白他们扮演的不同角色.

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

我读过关于Passenger,我真的不明白它是什么,网站说"使部署Ruby Web应用程序很轻松",它替换Mongrel?是否像Capistrano,它还部署Web应用程序?

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

感谢



解决方法

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

历史注释:本文最初是在2010年11月6日撰写的,那时Ruby应用服务器生态系统有限.我已于2013年3月15日更新此文章,其中包含生态系统中的所有最新更新.

免责声明:我是Phusion Passenger的作者之一,其中一个应用服务器.

Apache vs Nginx

它们都是网络服务器.它们可以投放静态文件,但使用正确的模块,还可以投放动态网络应用,例如那些用PHP编写的. Apache更受欢迎,并且有更多的功能,Nginx更小,更快,具有更少的功能.

Apache和Nginx都不能为Ruby Web应用程序提供开箱即用的服务,您需要使用Apache / Nginx与某种加载项结合使用,稍后再说.

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

Mongrel and other production app servers vs WEBrick

Mongrel是一个Ruby应用服务器:具体来说,这意味着Mongrel是一个应用程序,它:

  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.

然而,Mongrel是相当过时的,现在它不再维护.较新的替代应用程序服务器是:

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

稍后我会介绍他们,并描述他们彼此之间以及Mongrel之间的区别.

WEBrick和Mongrel做同样的事情,但不同的是:

  • 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

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

  • 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.

为什么有些应用程式伺服器必须放在逆向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.

为什么有些应用程式伺服器会直接显示在网际网路上?

  • 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

在本节中,我将比较我提到的大多数应用程序服务器,但不是Phusion Passenger. Phusion乘客是一个不同的野兽,我给了它一个专门的部分.我也省略了特立尼达和TorqueBox,因为我不太了解他们,但如果你使用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 的工作方式与所有其他工作方式截然不同. Phusion Passenger直接集成到Apache或Nginx中,因此可以与Apache的mod_php进行比较.就像mod_php允许Apache服务PHP应用程序一样,几乎神奇的是,Phusion Passenger允许Apache(和Nginx!)几乎神奇地服务Ruby应用程序. Phusion乘客的目标是使一切正常工作(tm)尽可能少的麻烦.

不要为您的应用程序启动一个进程或集群,而是配置Apache / Nginx为Phusion Passenger提供静态文件和/或反向代理请求到进程/集群,您只需要:

  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.

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

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

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

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

Phusion Passenger vs other app servers

Phusion Passenger提供了许多其他应用程式伺服器的功能,并提供许多优点,例如:

  • 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".

Unicorn不擅长的工作负载是:

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

Phusion Passenger Enterprise 4 或更高版本中的混合I / O模型使其成为这些各种工作负载.

  • 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.

有更多的特点和优点,但列表真的很长.您应参阅全面的Phusion Passenger手册( Apache版本, Nginx版本)或 Phusion Passenger网站.

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.

最近在Phusion博客上发布了一篇文章,介绍如何优化调整您的工作负载的进程和线程数.请参见调整Phusion Passenger的并发设置. / p>

Capistrano

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

  • 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.

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

Capistrano总是与应用程序服务器结合使用.它不会替换应用程序服务器.反之亦然,应用程序服务器不会替换Capistrano,它们可以与Capistrano组合使用.

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




相关问题推荐