我希望了解Nginx和Unicorn之间的区别。据我所知,Nginx是一个Web服务器,而Unicorn是一个Ruby HTTP服务器。
既然Nginx和Unicorn都可以处理HTTP请求,为什么需要在RoR应用程序中使用Nginx和Unicorn的组合呢?
我希望了解Nginx和Unicorn之间的区别。据我所知,Nginx是一个Web服务器,而Unicorn是一个Ruby HTTP服务器。
既然Nginx和Unicorn都可以处理HTTP请求,为什么需要在RoR应用程序中使用Nginx和Unicorn的组合呢?
Nginx是一个纯粹的Web服务器,用于提供静态内容和/或将请求重定向到另一个套接字以处理请求。
Unicorn是一个Rack Web服务器,仅用于托管'Rack App',通常生成动态内容。Rack应用程序也可以提供静态内容,但不如大多数其他传统Web服务器高效。
大多数RoR设置使用传统Web服务器和Rack服务器的组合来应用它们的最佳功能。 Nginx通过代理平衡和提供静态内容非常快速地进行请求重定向。 Unicorn能够很好地处理HTTP头并平衡传入请求以供Ruby处理。
这个答案是对其他答案的补充,解释了为什么Unicorn需要在其前面部署nginx。
简言之,Unicorn通常与反向代理(如nginx)一起部署的原因是因为它的创建者有意设计成这样,以简单为代价进行折衷。
首先,没有什么阻止你在不使用反向代理的情况下部署Unicorn。但是,这不是一个很好的主意;让我们看看为什么。
Unicorn遵循Unix哲学,即“专注于做一件事且做到极致”,即提供快速、低延迟的客户端服务(我们稍后会看到这意味着什么)。Unicorn被设计用于快速、低延迟的客户端服务,也意味着它在处理慢速、高延迟的客户端方面并不擅长,这一点确实正确。这是Unicorn的弱点之一,反向代理就是应对这些慢客户端的手段(我们稍后会看到如何)。
幸运的是,这样的反向代理已经存在,叫做nginx。
只处理快速客户端这一决策极大地简化了Unicorn的设计,使代码库更简单、更小,代价是在部署时增加一些复杂性(即需要额外部署nginx以外的Unicorn)。
另一个选择是以这样的方式设计Unicorn,以使其不需要反向代理。然而,这意味着它必须实现额外的功能来完成现在nginx所做的所有事情,从而导致更复杂的代码库和更多的工程努力。
相反,其创建者决定利用现有的经过实战测试且设计非常良好的软件,并避免浪费时间和精力在已经被其他软件解决的问题上。
但让我们变得技术化并回答你的问题:
为什么Unicorn需要与nginx一起部署?
以下是一些关键原因:
依靠反向代理意味着Unicorn不必使用非阻塞式I/O。相反,它可以使用阻塞式I/O,这在程序员看来本质上更简单且易于跟踪。
此外,正如设计文档所述:
[使用阻塞式I/O] 允许在Ruby解释器内遵循更简单的代码路径,并减少系统调用。
然而,这也有一些后果:
(为了简化起见,我们假设设置了1个Unicorn工作进程)
由于使用了阻塞式I/O,一个Unicorn工作进程一次只能服务于一个客户端,因此一个慢速客户端(即连接缓慢的客户端)会使该工作进程忙碌更长时间(比快速客户端多花费的时间)。同时,其他客户端将等待,直到该工作进程再次空闲(即请求会排队等待)。
为了解决这个问题,在Unicorn前部署了一个反向代理,它会完全缓冲传入请求以及应用响应,然后分别将它们一次性地发送(也就是逐个提供)给Unicorn和客户端。在这方面,可以说反向代理"保护"Unicorn免受网络缓慢的影响。
幸运的是,Nginx是这种角色的绝佳候选人,因为它设计用于高效地处理数千个并发客户端。
重要的是,反向代理应该与Unicorn在同一个本地网络中(通常是在同一个物理机器上通过Unix域套接字与Unicorn通信),以便将网络延迟降至最低。
因此,这样的代理实际上扮演着 Unicorn 最初设计要服务的 快速客户端 的角色,因为它将请求代理到 Unicorn 上 快速 并且尽可能地使工作进程保持繁忙状态,以确保相对于使用缓慢连接的客户端所需时间而言,最短的时间内完成请求。
由于 Unicorn 使用阻塞 I/O,这也意味着它无法支持 HTTP/1.1 keep-alive 特性,因为缓慢客户端的持久连接将很快占用所有可用的 Unicorn 工作进程。
因此,为了利用 HTTP keep-alive,猜猜看:需要使用反向代理。
另一方面,nginx 可以使用仅使用少量线程处理数千个并发连接。因此,它没有像 Unicorn 这样的服务器那样具有并发限制(本质上是限制 worker 进程的数量),这意味着它可以很好地处理持久连接。更多关于它如何实现的信息可以在这里找到。
这就是为什么 nginx 接受来自客户端的 keep-alive 连接并通过通常的 Unix 套接字以普通连接的方式代理它们到 Unicorn 上的原因。
同样,提供静态文件服务是 Unicorn 能够 完成的任务,但不是设计为高效完成的。
反向代理如nginx则更擅长此类任务(如sendfile(2)
和缓存)。
在PHILOSOPHY文档中还有其他要点(见“通过反向代理提高性能”)。
另请参阅 nginx 的基本特性。
通过利用现有软件(即 nginx)并遵循“做一件事情并把它做好”的 Unix 哲学,Unicorn 能够在维持为 Rack 应用程序提供高效服务的同时,遵循更简单的设计和实现。
要了解更多信息,请参考 Unicorn 的哲学和设计文档,这些文档详细说明了 Unicorn 设计背后的选择以及为什么认为 nginx 是 Unicorn 的好反向代理。
Nginx
Unicorn
请参考 GitHub 上的 Unicorn 以获取更多信息。
Nginx可以用来为unicorn服务器提供服务,因为慢速客户端会使unicorn服务器崩溃。Nginx被用作一种代理,缓冲所有请求和响应以适应慢速客户端。