当前位置: 首页 > 知识库问答 >
问题:

Nginx反向代理到Django接收'上游过早关闭连接,同时从上游读取响应头'

骆磊
2023-03-14

当Nginx试图通过http反向代理到本地Django实例(没有WSGI中间件)时,当Nginx从上游读取响应头时记录上游过早关闭的连接时,会发生什么http/tcp现象?

冒着激怒社区的风险,我不打算包含任何配置,虽然我确信它是相关的,但我试图理解这种现象背后的理论。

我和一些队友维护了一个供内部使用的Web服务器。在我们内部工具的世界里,东西永远不会被生产出来。我们通常会做任何必要的事情,为同事带来一些价值。风险和可用资源都很低。

因此,我们已经犯下了一个重大的错误,那就是单独安装Python2 Django服务器。没有WSGI中间件,没有其他流程。我看到了警告,但我们做了我们所做的。

最近,我在这个令人讨厌的东西面前放了一个Nginx实例,让我们能够在零停机的情况下“热交换”web应用程序实例。我仍然没有在两者之间插入任何内容。Nginx只是通过localhost http反向代理到在localhost非标准端口上侦听的Django实例。

在这个变化之后,我们开始看到来自Nginx的502的爆发。有几个页面是“实时的”,因为他们会做一些轮询来检查更新。因此,我们拥有的用户数量有“很多”流量。

实际上,我认为无论问题是什么,在Nginx推出之前就已经存在了,但是,由于浏览器直接得到了错误,它只是重新尝试,打嗝对用户来说是不可见的,而现在他们得到了一个丑陋的502错误消息。

现在问一个问题:如果我看到Nginx错误。当从上游读取响应头时,日志上游提前关闭连接这实际上意味着什么?我在这个网站上看到了很多关于修改配置的建议,这些建议似乎都不适用于我,但我想要的是理论。

这个错误意味着什么?当Nginx试图将请求代理给Django时,它到底经历了什么?Django拒绝联系吗?Django是否在连接完成之前关闭连接?

如果Django正在做这些事情,为什么?是内存溢出,线程,是否有一些原因会限制线程的数量,等等?

作为一次临时修复的盲目尝试,我在周末修复了应用程序的第二个实例,并将Nginx配置为循环负载平衡。这似乎奏效了,但我要到周一早上高峰负荷到来时才能确定。

第二个实例在同一个框中,因此不能有任何额外的系统资源。Python解释器实例中是否有一些资源正在耗尽,以至于创建第二个实例会给我“两倍”的容量?

除了“投入更多资源”之外,我真的在努力学习一些有价值的东西

任何帮助都将不胜感激。提前谢谢!

菲利普,非常感谢你彻底的回答!一个简单的问题来锁定我的理解...

如果我的上游Python服务器“无法并行处理足够多的请求并阻塞”,那么这可能是什么原因呢。这是一个单一的过程,所以我认为这可以简化问题。什么资源会耗尽?难道服务器不可能以任何速度读取套接字吗?什么样的系统/服务器配置决定了它一次可以处理的飞行中请求的数量?我仔细查看了一下,没有发现任何显式的Django(Python服务器库)配置选项会人为地限制其响应能力。我当然可以提供额外的资源,但如果更多的是系统限制,那么我不希望同一个盒子上的另一个实例能做任何事情(这是我现在所期望的,因为第二个实例在周末开始产生同样的问题)。我想在这里一劳永逸地做出一个经过深思熟虑的决定。

再次感谢您(或任何其他人)的帮助!

根本的问题(正如一位精通Linux内核的同事在我周一早上进入时向我描述的那样)是侦听队列深度。

正是这种结构的能力有限。当一个进程监听一个端口,新的连接尝试出现时(在连接建立之前),如果该进程建立连接的速度比建立连接的速度慢,就会产生监听队列。

因此,这与内存或CPU无关(除非这些资源的短缺是连接建立缓慢的原因),而是对进程连接能力的限制。

我绝对不是这方面的专家,但我所追求的正是这种构造,它解释了为什么一个给定的进程突然决定(或操作系统决定)不再接受连接。

更多信息可以在这里阅读。

再次感谢菲利普带领我走上正确的道路!


共有2个答案

左丘子平
2023-03-14

也许你已经检查过了,但是我昨天遇到了一个类似的问题,问题是:我正在运行uwsgi--超文本传输协议-ocket: 5000。我已经更改为--ocket: 5000,它工作得很好。

我希望这能帮助别人。

凤昊东
2023-03-14
匿名用户

上游在从上游读取响应头时过早关闭连接

这个错误肯定在上游,这意味着在您的情况下,连接到Python服务器。502表示从Nginx到其上游服务器之一的TCP连接已关闭(从python进程主动关闭,或在超时时由系统关闭)。

从您描述的情况来看,可能是Python服务器无法并行和分块处理足够多的请求。只要前面没有Nginx,您就不会注意到,可能只是请求很慢。随着Nginx的出现,它会发生变化,因为Nginx可以轻松处理大量请求,并且可能会接受比其上游服务器(即Python服务器)能够跟上的更多请求。在这种情况下,上游服务器没有响应,最终套接字被关闭,这迫使Nginx在502(坏网关)时失败。

为了测试这一理论,您需要比较向Nginx或直接向Python服务器发出多个请求时会发生什么。当您直接转到Python服务器时,It请求被阻塞,服务速度变慢(但没有错误),但当您转到Nginx时,所有请求都立即被接受(但有些请求在502中失败),这可能是我描述的情况。

在这种情况下,您可以尝试以下几点:

  • 确保保持活力在Nginx上有效(这是一个好主意,应该限制上游的并行请求数量)。有关详细信息,请参见此答案。
  • (如果可能的话)改变Python服务器,这样它们就可以处理更多的并行请求
  • 确保服务器上的文件句柄没有用完,并监控系统上TPC套接字的数量(例如,使用sudo netstat-tulpan)。

我可能错了,因为我在回答中做了很多猜测。尽管如此,我希望它能给你一些解决请求关闭(或超时)原因的想法。

 类似资料:
  • 问题内容: 他们似乎遇到了类似的问题,但该解决方案对我不起作用。 基本上,每当我尝试启动uWSGI进程时,我总是遇到Nginx 502错误的网关屏幕。按照文档中的说明,我有两个独立的uwsgi进程正在运行。 当我运行websocket uwsgi实例时,得到以下信息: 这告诉我uwsgi实例运行正常。然后我运行我的下一个uwsgi进程,并且那里也没有错误日志… 当我导航到浏览器中的页面时,带有ha

  • 问题内容: 我正在使用nginx和节点服务器来处理更新请求。当我请求大数据更新时,我收到网关超时。我从nginx错误日志中看到了此错误: 2016/04/07 00:46:04 [错误] 28599#0:* 1上游过早关闭连接,同时从上游读取响应标头,客户端:10.0.2.77,服务器:gis.oneconcern.com,请求:“ GET / update_mbtiles / atlas1989

  • 我正在使用nginx和节点服务器来服务更新请求。当我请求更新大数据时,我会得到一个网关超时。我从nginx错误日志中看到了这个错误: 节点js代码: 谢谢你。

  • 你好吗?我在DigitalOcean上有一个使用Ubuntu16.04的服务器,我正在用uWSGI和Nginx制作一个Flask应用程序。 我的文件如下所示:wsgi.py: 非常感谢!!! 我该如何解决?

  • 我有Puma运行作为上游应用服务器和Riak作为我的后台数据库集群。当我发送一个请求,为大约25K用户映射-减少一个数据块,并将其从Riak返回到应用程序时,我在Nginx日志中得到一个错误: Nginx有一系列超时指令。我不知道我是不是漏掉了什么重要的东西。如有任何帮助将不胜感激....

  • 我在一个flask应用程序上使用nginx+uwsgi。在nginx设置中,服务器块具有server_name*.mydomain.com;uwsgi的位置块如下所示 我有另一个测试设置,其中所有这些设置是相同的,它的工作。有什么指示吗?当我重新启动uwsgi和nginx时,app1.mydomain.com工作,直到我加载app.mydomain.com(初始加载app.mydomain.com