我有一个在 Gunicorn 上运行的 Django 网站,并通过 Nginx 进行反向代理。Nginx 难道不只是额外的不必要的开销吗?在 Gunicorn 之上添加它有什么帮助?
答案1
我将重点介绍缓慢的客户端行为以及您的配置如何处理它,但不要以为这就是唯一的好处。对缓慢的客户端有益的方法对快速的客户端、SSL 处理、处理流量激增以及在 Internet 上提供 HTTP 服务的其他方面也有好处。
Gunicorn 是一款预分叉软件。对于低延迟通信(例如负载均衡器到应用服务器或服务之间的通信),预分叉系统可能非常成功。启动一个进程来处理请求没有任何成本,并且可以将单个进程专用于处理单个请求;消除这些因素可以使系统整体更快、更高效,直到同时连接的数量超过可用于处理的进程数量。
在您的情形下,您正在处理互联网上的高延迟客户端。这些慢速客户端可能会占用相同的进程。当 QPS 很重要时,应用程序代码需要尽快接收、处理和解析请求,以便可以继续处理另一个请求。当慢速客户端直接与您的系统通信时,它们会占用该进程并使其变慢。该进程现在还必须等待慢速客户端,而不是尽快处理和处置请求。有效 QPS 会下降。
以极低的 CPU 和内存成本处理大量连接是 Nginx 等异步服务器的强项。它们不会受到缓慢客户端的负面影响,因为它们擅长同时处理大量客户端。就 Nginx 而言,在现代硬件上运行,它可以同时处理数万个连接。
Nginx 位于预分叉服务器前面是一个很好的组合。Nginx 处理与客户端的通信,并且不会因处理速度慢的客户端而受到惩罚。它会以后端处理这些请求的速度向后端发送请求,从而使后端尽可能高效地利用服务器资源。后端在计算结果后立即返回结果,而 Nginx 会缓冲该响应,以自己的速度将其提供给速度慢的客户端。同时,即使速度慢的客户端仍在接收结果,后端也可以继续处理另一个请求。
答案2
@blueben 是对的。不使用反向代理时可能发生的一个具体而常见的例子是,在没有代理的情况下,后端数据库可能会用尽数据库连接句柄,并且流量激增。这是因为正如 @blueben 所描述的,连接释放速度很慢。
看到数据库句柄耗尽时,第一个反应可能是支持更多数据库连接。但是通过在应用程序前面添加反向代理,您会看到高负载所需的数据库连接数显著下降并趋于稳定——当流量激增时,数据库连接水平不会激增那么多。
Nginx 还擅长提供静态内容、缓存和各种其他 HTTP 任务,让您的应用服务器专注于作为应用服务器。
答案3
@naill Donegan 在上面的评论中提到了这一点,但它足够重要,值得回答。
Nginx 阻止了 gunicorn 无法处理的懒猴攻击。