为啥 Unicorn 需要和 Nginx 一起部署?

Posted

技术标签:

【中文标题】为啥 Unicorn 需要和 Nginx 一起部署?【英文标题】:Why does Unicorn need to be deployed together with Nginx?为什么 Unicorn 需要和 Nginx 一起部署? 【发布时间】:2012-02-03 02:55:50 【问题描述】:

我想知道 nginx 和 Unicorn 的区别。据我了解,Nginx 是 Web 服务器,而 Unicorn 是 Ruby HTTP 服务器。

既然 Nginx 和 Unicorn 都可以处理 HTTP 请求,那么在 RoR 应用中需要使用 Nginx 和 Unicorn 的组合吗?

【问题讨论】:

好问题!我认为这个问题的标题应该是,“为什么我们需要 nginx 和 unicorn 的组合。;) 答案对我很有帮助。 @servatj 我添加了一个答案,更详细地解释了为什么 Unicorn 需要像 Nginx 这样的反向代理。你可能想看看;) 【参考方案1】:

Nginx 可用于在独角兽服务器上为慢速客户端提供服务,因为慢速客户端会阻塞独角兽服务器。 Nginx 被用作某种代理,缓冲所有对慢速客户端的请求和响应。

见http://unicorn.bogomips.org/

【讨论】:

【参考方案2】:

Nginx 独角兽 请参阅unicorn on github 了解更多信息。

【讨论】:

Pratik,我的问题是 unicorn 服务器可以同时服务于静态和动态进程,那么为什么我们使用 NGinx 或 Apache 那些可以处理唯一静态内容,结合乘客或 unicorn 或 mod_php @loganathan,Apache 和 Nginx 在提供静态内容方面都比 ruby​​ 或任何应用程序服务器快得多。他们还知道如何处理缓存,并且擅长允许并发文件下载,同时仍然接收流量并将其传递给应用程序服务器。 另外,如果你有大量的数据传入和传出,nginx 将从客户端缓冲它(和勺子馈送)。如果没有 nginx,您的独角兽之一将在上传/下载期间被捆绑。 这并没有回答为什么需要 nginx 的问题。它只是把它放在两张照片中,没有任何评论。尼克的回答要好得多。 我同意@gorn。例如,这对我来说毫无意义。【参考方案3】:

Nginx 是一个纯 Web 服务器,旨在提供静态内容和/或将请求重定向到另一个套接字以处理请求。

Unicorn 是一个 Rack Web 服务器,仅用于托管通常生成动态内容的“Rack App”。机架应用也可以提供静态内容,但效率低于大多数其他传统 Web 服务器。

大多数 RoR 设置结合使用传统的 Web 服务器和机架服务器,以充分利用它们的两种功能。 Nginx 通过代理平衡和提供静态内容的请求重定向速度非常快。 Unicorn 非常有能力处理 HTTP 标头并平衡对 Ruby 进行处理的入站请求。

【讨论】:

【参考方案4】:

这个答案是对其他答案的补充,并解释了为什么 Unicorn 在它前面需要 nginx

TL;DR Unicorn 通常与像 nginx 这样的反向代理一起部署的原因是它的创建者故意这样设计它,为了简单而做出权衡。

首先,没有什么可以阻止您在没有反向代理的情况下部署 Unicorn。但是,这不是一个好主意。让我们看看为什么。

Unicorn 遵循 Unix 哲学,即做好一件事,即为快速、低延迟的客户提供服务(我们将看看这意味着稍后)。 Unicorn 是为快速、低延迟的客户端设计的这一事实也意味着它不太适合慢、高延迟的客户端,这确实是事实。这是 Unicorn 的弱点之一,也是反向代理发挥作用的地方:它位于 Unicorn 前面,负责处理那些慢客户端(我们将看到如何稍后)。

幸运的是,这样的反向代理已经存在,名为nginx。

只处理快速客户端的决定大大简化了 Unicorn 的设计,并允许更简单和更小的代码库,但代价是增加了部署部门的复杂性(即,除了 Unicorn 之外,您还必须部署 nginx )。

另一种选择是设计 Unicorn,使其不需要反向代理。然而,这意味着它必须实现额外的功能来完成现在 nginx 所做的所有事情,从而导致更复杂的代码库和更多的工程工作。

相反,它的创建者决定利用经过实战考验且设计精良的现有软件,避免将时间和精力浪费在其他软件已经解决的问题上。

但是,让我们获得技术并回答您的问题:

为什么Unicorn需要和nginx一起部署?

以下是一些关键原因:

Unicorn 为客户端使用阻塞 I/O

依赖反向代理意味着 Unicorn 不需要 使用非阻塞 I/O。相反,它可以使用阻塞 I/O,这本质上更简单,程序员也更容易遵循。

正如DESIGN 文档所述:

[使用阻塞 I/O] 允许在 Ruby 解释器中遵循更简单的代码路径并减少系统调用。

不过,这也有一些后果:

关键点 #1:独角兽对慢速客户端效率不高

(为简单起见,我们假设设置有 1 个独角兽工人)

由于使用了阻塞 I/O,Unicorn worker 一次只能为一个客户端提供服务,因此慢速客户端(即连接速度慢的客户端)会有效地让 worker 忙于更长的时间(比快速客户端会做的)。与此同时,其他客户端只会等到 worker 再次空闲(即请求会堆积在队列中)。

为了解决这个问题,在 Unicorn 前面部署了一个反向代理,它完全缓冲传入的请求应用程序响应,然后发送它们中的每一个一次(又名勺子喂他们)分别给独角兽和客户。在这方面,您可以说反向代理“屏蔽”了 Unicorn 免受慢速网络客户端的影响。

幸运的是,Nginx 是这个角色的绝佳人选,因为它旨在高效地处理数千个并发客户端。

至关重要的是,反向代理应与 Unicorn 位于同一本地网络中(通常位于通过 Unix 域套接字与 Unicorn 通信的同一物理机器中),以便将网络延迟保持在最低限度。

因此,这样的代理有效地扮演了 Unicorn 最初设计为服务的 快速客户端 的角色,因为它代理对 Unicorn fast 的请求并保持工作人员忙于尽可能短的时间(与连接速度较慢的客户端所需的时间相比)。

关键点#2:Unicorn 不支持 HTTP/1.1 keep-alive

由于 Unicorn 使用阻塞 I/O,这也意味着它无法支持 HTTP/1.1 的 keep-alive 功能,因为慢速客户端的持久连接会很快占用所有可用的 Unicorn worker。

因此,为了利用 HTTP 保持活动,猜猜看:使用了反向代理。

另一方面,nginx 只需几个线程就可以处理数千个并发连接。因此,它没有像 Unicorn 这样的服务器的并发限制(基本上限制了工作进程的数量),这意味着它可以很好地处理持久连接。可以在here 找到更多实际工作原理。

这就是为什么 nginx 接受来自客户端的 keep-alive 连接,并通过通常通过 Unix 套接字的普通连接将它们代理到 Unicorn。

第 3 点:Unicorn 不太擅长提供静态文件

再次重申,提供静态文件是 Unicorn可以 做的事情,但设计目的不是为了高效。

另一方面,像 nginx 这样的反向代理虽然在这方面做得更好(即sendfile(2) 和缓存)。

更多

PHILOSOPHY 文档中概述了其他要点(请参阅“通过反向代理提高性能”)。

另见nginx's basic features。

我们看到,通过利用现有软件(即 nginx)并遵循“做一件事,做好”的 Unix 理念,Unicorn 能够遵循更简单的设计和实现,同时保持高效地为 Rack 应用程序提供服务(例如,您的 Rails 应用程序)。

有关更多信息,请参阅 Unicorn 的 philosophy 和 design 文档,其中更详细地解释了 Unicorn 设计背后的选择以及为什么 nginx 被认为是 Unicorn 的良好反向代理。

【讨论】:

但是为什么不直接使用 Nginx 我想他是在问,而不是“为什么独角兽需要 nginx”。例如,Unicorn 提供了 Nginx 没有提供的什么? @oMiKeY 如果是这样,我相信其他答案很好地解决了这个问题。我仍然认为我的回答为任何试图了解 nginx 和 unicorn 的组合的人提供了有用的信息。 这是纯金。谢谢!

以上是关于为啥 Unicorn 需要和 Nginx 一起部署?的主要内容,如果未能解决你的问题,请参考以下文章

Ruby on Rails全栈课程5.5 项目上线--nginx+unicorn部署项目域名映射

rails 4.1.0.rc1 nginx 和 unicorn 未在生产环境中提供资产

我可以将 SPDY 与 Unicorn 一起使用吗?

带有 nginx 和 unicorn 的 Django 静态文件

部署 Rails4:/socket/.unicorn.sock 在连接上游时失败(2:没有这样的文件或目录)

使用 unicorn 将 Rails 应用程序部署到 Opsworks 时出错