Ruby-on-rails 为什么 Unicorn 需要和 Nginx 一起部署?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8739871/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why does Unicorn need to be deployed together with Nginx?
提问by loganathan
I would like to know the difference between Nginx and Unicorn. As far as I understand, Nginx is a web server while Unicorn is a Ruby HTTP server.
我想知道 Nginx 和 Unicorn 之间的区别。据我了解,Nginx 是一个 Web 服务器,而 Unicorn 是一个 Ruby HTTP 服务器。
Since both Nginx and Unicorn can handle HTTP requests, what is the need to use the combination of Nginx and Unicorn for RoR applications?
既然 Nginx 和 Unicorn 都可以处理 HTTP 请求,那么在 RoR 应用中使用 Nginx 和 Unicorn 的组合有什么必要呢?
采纳答案by Pratik
Nginx
Unicorn
Refer to unicorn on githubfor more information.
回答by Nick
Nginx is a pure web server that's intended for serving up static content and/or redirecting the request to another socket to handle the request.
Nginx 是一个纯 Web 服务器,用于提供静态内容和/或将请求重定向到另一个套接字以处理请求。
Unicorn is a Rack web server and only intended to host a 'Rack App' which is usually generating dynamic content. Rack apps can also serve up static content but it's less efficient than most other traditional web servers.
Unicorn 是一个 Rack Web 服务器,仅用于托管通常生成动态内容的“Rack App”。Rack 应用程序也可以提供静态内容,但它的效率低于大多数其他传统 Web 服务器。
Most RoR setups use a combination of both traditional web servers and Rack servers to apply the best of both of their capabilities. Nginx is incredibly fast at request redirection through proxy balancing and serving up static content. Unicorn is quite capable of processing HTTP headers and balancing inbound requests to Ruby for processing.
大多数 RoR 设置使用传统 Web 服务器和机架服务器的组合来应用它们的最佳功能。Nginx 通过代理平衡和提供静态内容在请求重定向方面非常快。Unicorn 非常有能力处理 HTTP 标头并平衡对 Ruby 的入站请求进行处理。
回答by Agis
This answer is complementary to the other ones and explains why Unicorn needs nginx in front of it.
这个答案是对其他答案的补充,并解释了为什么 Unicorn 在它前面需要 nginx。
TL;DR The reason that Unicorn is usually deployed together with a reverse proxy like nginx is because its creators deliberately designed it so, making a tradeoff for simplicity.
TL;DR Unicorn 通常与像 nginx 这样的反向代理一起部署的原因是因为它的创建者故意这样设计它,为了简单而进行权衡。
First of all, there's nothing keeping you from deploying Unicorn withouta reverse proxy. However, that wouldn't be a very good idea; let's see why.
首先,没有什么可以阻止您在没有反向代理的情况下部署 Unicorn 。然而,这不是一个好主意。让我们看看为什么。
Unicorn follows the Unix philosophy which is to do one thing and do it well, and that is to serve fast, low-latency clients(we'll see what this means later on). The fact that Unicorn is designed for fast, low-latency clientsalso implies that it's not very good with slow, high-latency clients, which is indeed true. This is one of Unicorn's weak points and it's where a reverse proxy comes into play: it sits in front of Unicorn and takes care of those slow clients(we'll see howlater on).
Unicorn 遵循 Unix 哲学,即做一件事并做好它,即为快速、低延迟的客户端提供服务(稍后我们将看到这意味着什么)。Unicorn 是为快速、低延迟的客户端设计的这一事实也意味着它对于慢速、高延迟的客户端并不是很好,这确实是事实。这是 Unicorn 的弱点之一,也是反向代理发挥作用的地方:它位于 Unicorn 前面,负责处理那些慢速客户端(我们稍后会看到如何处理)。
Fortunately, such a reverse proxy already exists and is called nginx.
幸运的是,这样的反向代理已经存在,叫做nginx。
The decision to handle only fast clients, greatly simplifies the design of Unicorn and allows a much simpler and smaller codebase, at the cost of some added complexity on the deployment department (ie. you have to deploy nginx too in addition to Unicorn).
仅处理快速客户端的决定极大地简化了 Unicorn 的设计,并允许更简单和更小的代码库,但代价是部署部门的一些复杂性增加(即,除了 Unicorn 之外,您还必须部署 nginx)。
An alternative decision could be designing Unicorn in such a way that it wouldn't need a reverse proxy. However, this means that it would have to implement extra functionality to do all the things that now nginx does, resulting in a more complex codebase and more engineering efforts.
另一种决定可能是以不需要反向代理的方式设计 Unicorn。然而,这意味着它必须实现额外的功能来完成现在 nginx 所做的所有事情,从而导致更复杂的代码库和更多的工程工作。
Instead its creators made the decision to leverage existing software that is battle-tested and very well designed and to avoid wasting time and energy on problems already solved by other software.
相反,它的创建者决定利用经过实战测试且设计精良的现有软件,并避免在其他软件已经解决的问题上浪费时间和精力。
But let's get technical and answer your question:
但是让我们从技术角度回答你的问题:
Why does Unicorn needs to be deployed together with nginx?
为什么 Unicorn 需要和 nginx 一起部署?
Here are some of the key reasons:
以下是一些关键原因:
Unicorn uses blocking I/O for clients
Unicorn 为客户端使用阻塞 I/O
Relying on a reverse proxy means that Unicorn doesn't needto use non-blocking I/O. Instead it can use blocking I/O which is inherently simpler and easier for the programmer to follow.
依赖反向代理意味着 Unicorn不需要使用非阻塞 I/O。相反,它可以使用阻塞 I/O,这在本质上更简单,更容易让程序员遵循。
Also as the DESIGNdocument states:
同样如DESIGN文件所述:
[Using blocking I/O] allows a simpler code path to be followed within the Ruby interpreter and fewer syscalls.
[使用阻塞 I/O] 允许在 Ruby 解释器中遵循更简单的代码路径和更少的系统调用。
However, this also has some consequences:
然而,这也有一些后果:
Key point #1: Unicorn is not efficient with slow clients
关键点#1:Unicorn 对慢速客户端效率不高
(For simplicity's sake, we assume a setup with 1 Unicorn worker)
(为简单起见,我们假设设置有 1 个 Unicorn worker)
Since blocking I/O is used, a Unicorn worker can only serve one client at a time, so a slow client (ie. one with a slow connection) would effectively keep the worker busy for a longer time (than a fast client would do). In the meantime, the other clients would just wait until the worker is free again (ie. requests would pile up in the queue).
由于使用了阻塞 I/O,Unicorn worker 一次只能为一个客户端提供服务,因此慢速客户端(即连接速度较慢的客户端)将有效地使 worker 忙碌更长的时间(比快速客户端更有效) )。与此同时,其他客户端只会等到工作人员再次空闲(即请求会堆积在队列中)。
To get around this issue, a reverse proxy is deployed in front of Unicorn, that fully buffersincoming requests and?the application responses, and then sends each of them?at once(aka spoon-feeds them)?to Unicorn and the clients, respectively. In that regard, you could say that the reverse proxy "shields" Unicorn from slow network clients.
为了解决这个问题,在 Unicorn 前面部署了一个反向代理,它完全缓冲传入的请求和应用程序响应,然后发送它们中的每一个?立即(也就是用勺子喂它们)?分别给独角兽和客户。在这方面,您可以说反向代理“屏蔽”了 Unicorn 免受慢速网络客户端的攻击。
Fortunately Nginx is a great candidate for this role, since it is designed to handle thousands of hundreds concurrent clients efficiently.
幸运的是,Nginx 是这个角色的绝佳候选者,因为它旨在有效地处理数千个并发客户端。
It's of crucial importance that the reverse proxy should be?within the same local network?as Unicorn (typically in the same physical machine communicating w/ Unicorn via a Unix domain socket), so that the network latency is kept to a minimum.
反向代理应该与 Unicorn 位于同一本地网络中(通常在同一台物理机器中,通过 Unix 域套接字与 Unicorn 通信)至关重要,以便将网络延迟保持在最低限度。
So such a proxy effectively plays the role of a fast client?that Unicorn is designed to serve in the first place, since it proxies requests to Unicorn fastand keeps the workers busy for the shortest possible amount of time(compared to how much time a client with a slow connection would do).
因此,这样的代理有效地扮演了快速客户端的角色? Unicorn 的设计初衷是为 Unicorn 提供服务,因为它可以快速代理对 Unicorn 的请求,并使工作人员在尽可能短的时间内保持忙碌(与连接速度较慢的客户端会这样做)。
Key point #2: Unicorn does not support HTTP/1.1 keep-alive
关键点#2:Unicorn 不支持 HTTP/1.1 keep-alive
Since Unicorn uses blocking I/O, it also means that it can't support the HTTP/1.1 keep-alive feature, since the persistent connections of slow clients would quickly occupy all the available Unicorn workers.
由于 Unicorn 使用了阻塞 I/O,这也意味着它不能支持 HTTP/1.1 的 keep-alive 特性,因为慢客户端的持久连接会很快占用所有可用的 Unicorn worker。
Therefore to leverage HTTP keep-alive, guess what: a reverse proxy is used.
因此,要利用 HTTP keep-alive,猜猜是什么:使用了反向代理。
nginx on the other hand, can handle thousands of concurrent connections using just a few threads. Therefore, it doesn't have the concurrency limits a server like Unicorn has (which essentially limited to the amount of worker processes), which means it can handle persistent connections just fine. More of how this actually works can be found here.
另一方面,nginx 可以使用几个线程处理数千个并发连接。因此,它没有像 Unicorn 这样的服务器的并发限制(基本上限制了工作进程的数量),这意味着它可以很好地处理持久连接。可以在此处找到有关其实际工作原理的更多信息。
That's why nginx accepts keep-alive connections from the clients and proxies them to Unicorn over plain connections via typically a Unix socket.
这就是为什么 nginx 接受来自客户端的保持活动连接,并通过普通的 Unix 套接字将它们代理到 Unicorn。
Point #3: Unicorn is not very good at serving static files
第 3 点:Unicorn 不太擅长提供静态文件
Again, serving static files is a thing that Unicorn cando but is not designed to do efficiently.
同样,提供静态文件是 Unicorn可以做的事情,但并非旨在有效地做。
On the otherhand, reverse proxies like nginx though are much more better at it (ie. sendfile(2)& caching).
另一方面,像 nginx 这样的反向代理在这方面要好得多(即sendfile(2)&缓存)。
More
更多的
There are other points which are outlined in the PHILOSOPHYdocument (see "Improved Performance Through Reverse Proxying").
PHILOSOPHY文档中概述了其他要点(请参阅“通过反向代理提高性能”)。
See also some of nginx's basic features.
We see that by leveraging existing software (ie. nginx) and following the Unix philosophy of "doing one thing and do it well", Unicorn is able to follow a simpler design and implementation while maintaining to be efficient at serving Rack apps (eg. your Rails app).
我们看到,通过利用现有软件(即 nginx)并遵循 Unix 哲学“做一件事并做好”,Unicorn 能够遵循更简单的设计和实现,同时保持高效地服务 Rack 应用程序(例如。您的 Rails 应用程序)。
For more information refer to Unicorn's philosophyand designdocuments which explain in more detail the choices behind Unicorn's design and why nginx is considered a good reverse-proxy for Unicorn.
有关更多信息,请参阅 Unicorn 的哲学和设计文档,其中更详细地解释了 Unicorn 设计背后的选择以及为什么 nginx 被认为是 Unicorn 的良好反向代理。
回答by bardiir
Nginx can be used to serve slow clients on a unicorn server as slow clients would choke the unicorn server. Nginx is used as some sort of proxy buffering all requests and responses to slow clients.
Nginx 可用于在独角兽服务器上为慢速客户端提供服务,因为慢速客户端会阻塞独角兽服务器。Nginx 用作某种代理来缓冲对慢速客户端的所有请求和响应。

