为什么我需要Nginx和诸如Gunicorn之类的东西?


219

我正在寻找以下问题的过于简化的答案。我正在尝试对Nginx与Gunicorn等产品的工作方式建立基础理解。

我是否需要Nginx和类似Gunicorn的东西才能在Nginx上部署Django应用?

如果是这样,那么实际处理HTTP请求的是什么?

附言 我不想使用Apache和mod_wsgi!


Apache和mod_wsgi是实现django应用程序与http请求之间的桥梁的最简单方法,在生产环境中也非常有用。对于许多开发人员来说,这意味着“ Apache比nginx更好”(如果他们知道但知道的话),但是由于“ betamax比VHS更好”,
Dog

Answers:


314

过于简化:您需要执行Python的程序,但是Python并不是处理所有类型请求的最佳方法。

[免责声明:我是Gunicorn开发人员]

简化程度较低:无论您使用哪种应用服务器(Gunicorn,mod_wsgi,mod_uwsgi,cherrypy),任何类型的非重要部署都会在上游进行处理,以处理您的Django应用不应处理的请求。此类请求的简单示例是提供静态资产(images / css / js)。

这导致了经典的“三层体系结构”的两个第一层。即,网络服务器(在您的情况下为Nginx)将处理许多对图像和静态资源的请求。然后,需要动态生成的请求将传递到应用程序服务器(在您的示例中为Gunicorn)。(顺便说一句,三层中的第三层是数据库)

从历史上讲,这些层中的每层都将托管在单独的计算机上(前两层中很可能会有多台计算机,即:5台Web服务器将请求分发到两个应用服务器,而这两个应用服务器又查询单个数据库)。

在现代时代,我们现在可以使用各种形状和尺寸的应用程序。并非每个周末的项目或小型企业站点实际上都需要多台计算机的功能,并且可以在一个盒子上运行得很愉快。这在托管解决方案阵列中产生了新的条目。一些解决方案会将应用程序服务器连接到Web服务器(Apache httpd + mod_wsgi,Nginx + mod_uwsgi等)。而且,将数据库与这些Web /应用程序服务器组合之一托管在同一台计算机上并不少见。

现在以Gunicorn为例,我们做出了一个特定的决定(从Ruby的Unicorn复制),以使事物与Nginx分开,同时依赖于Nginx的代理行为。具体来说,如果我们可以假设Gunicorn永远不会直接从互联网读取连接,那么我们就不必担心客户端运行缓慢。这意味着Gunicorn的处理模型非常简单。

这种分离还使Gunicorn可以用纯Python编写,从而在不显着影响性能的情况下将开发成本降至最低。它还允许用户使用其他代理(假设他们正确缓冲)的能力。

关于您的第二个问题,即实际处理HTTP请求的问题,简单的答案是Gunicorn。完整的答案是Nginx和Gunicorn都可以处理请求。基本上,Nginx会收到请求,如果它是一个动态请求(通常基于URL模式),则会将该请求提供给Gunicorn,后者将对其进行处理,然后将响应返回给Nginx,然后将其转发回原始请求。客户。

最后,是的。您需要Nginx和Gunicorn(或类似的东西)才能正确部署Django。如果您特别希望使用Nginx托管Django,那么我将研究Gunicorn,mod_uwsgi以及CherryPy作为Django方面的候选对象。


14
感谢您抽出宝贵的时间写出如此详细的答案!关于这种“三层体系结构”,是否有任何推荐的读物?

5
好的答案,但是我不明白慢客户端的问题。
Mads Skjern 2014年

3
@MadsSkjern我在这里猜测,但是如果您假设所有客户端都是快速的,那么您可以使用固定的工作进程池,而不必为其中很多或全部等待客户端阻塞的情况进行编码。
乔纳森·哈特利


7
我的Django应用仅提供json,没有静态内容,我可以只使用gunicorn,也不能使用nginx
Sar009,2016年

27

我喜欢这种解释的简单性:

Nginx将面对外界。它将直接从文件系统提供媒体文件(图像,CSS等)。但是,它无法直接与Django应用程序对话;它需要一些东西来运行应用程序,从网络上获取它的请求,并返回响应。

那是Gunicorn的工作。Gunicorn将创建一个Unix套接字,并通过wsgi协议提供对nginx的响应-套接字在两个方向上传递数据:

The outside world <-> Nginx <-> The socket <-> Gunicorn

https://gist.github.com/Atem18/4696071


不必是套接字,以防万一其他人想知道。
akshay

0

我正在寻找一个过于简化的答案...

我是否需要Nginx和类似Gunicorn的东西才能在Nginx上部署Django应用?

如果是这样,那么实际处理HTTP请求的是什么?

过于简化的答案:

是。

Nginx和Gunicorn。

由于要在Nginx上进行部署,因此您当然需要Nginx。

由于您正在部署Django(这是一个Web框架),因此需要一些桥接Web服务器(Nginx)和Web框架(Django)之间的对话的工具。在Python世界中,这种东西称为WSGI服务器(但认为它像中间件一样),例如Gunicorn和uWSGI。在处理请求时,Nginx将请求代理到Gunicorn或uWSGI,后者依次调用Django代码并返回响应。

该文档和Paul的回答将帮助您更好地学习。


0

独角兽是浪费资源。您可以简单地将pass传递给django并在端口上侦听,而不是在顶级django上运行gunicorn,再在所有这些之上运行nginx。在基准测试中,我看到了非常明显的速度提高。Nginx可以轻松处理对Django的直接请求。独角兽不过是正常道路上方的天桥(实际上是较慢的天桥)而已。它只是坐下来吃掉您的资源,并试图声称正在为您的网站提供动力。

nginx基本上会缓冲所有请求,并自行处理静态文件请求(如果已这样配置的话)。并将所有动态内容代理到另一台服务器。(gunicorn / django)。

Gunicorn除了将请求传递给应用程序外没有其他用途。这就像一根吸管,您可以直接从玻璃杯中喝水,也可以以有限的速度从吸管中喝水(此处的饮用者是django)。Nginx是为您带来一杯果汁的服务生。

我进行了基准测试,发现了这一点-带有gunicorn:22k req / s,不带gunicorn:34k req / s

您的站点将需要大量的额外请求。


1
您是在谈论在生产环境中运行开发服务器吗?
迈克尔·汉普顿

开发服务器可以在生产服务器(如nginx)后面运行。因为它将在正确的位置收到请求,并且安全性和效率将由生产服务器处理。就像只使​​用WSGI + flask。相反,您可以只使用nginx + django(无需任何中间件的干扰,例如gunicorn)。请在高负载下测试设置,您将了解。
ShadowDoom

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.