gpt4 book ai didi

django - Nginx 反向代理到 Django 接收 `upstream prematurely closed connection while reading response header from upstream`

转载 作者:行者123 更新时间:2023-12-04 10:58:35 31 4
gpt4 key购买 nike

TL; 博士

Nginx 日志时出现什么http/tcp 现象upstream prematurely closed connection while reading response header from upstream尝试通过 HTTP 将代理反向代理到本地 Django 实例(没有 WSGI 中间件)时?

长版

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

我和一些队友维护了一个网络服务器供内部使用。在/我们的内部工具世界中,事物永远不会被产品化。我们通常会做任何必要的事情来为我们的同事提供一些值(value)。风险和可用资源都很低。

因此,我们在建立自己的 Python 2 Django 服务器时犯了一个大罪。没有 WSGI 中间件,没有额外的进程。我已经看到了告诫,但我们已经完成了我们所做的。

我最近在这个可憎的事物面前建立了一个 Nginx 实例,让我们能够在零停机的情况下“热交换”我们的 Web 应用程序的实例。我仍然没有在两者之间插入任何东西。 Nginx 只是反向代理,通过 localhost http 到监听 localhost 非标准端口的 Django 实例。

在此更改之后,我们开始看到来自 Nginx 的 502 的爆发。有一些页面是“实时”的,因为它们会进行一些轮询以检查事物的更新。因此,我们拥有的用户数量有“大量”流量。

我实际上认为在引入 Nginx 之前已经存在任何问题,但是,由于浏览器直接收到错误,它只是重试并且打嗝对用户不可见,而现在他们收到了丑陋的 502 错误消息。

现在的问题:
如果我在 Nginx error.log 中看到 upstream prematurely closed connection while reading response header from upstream这实际上是什么意思?我在这个网站上看到了很多关于配置更改建议的帖子,但似乎没有一个适用于我,但我正在寻找的是理论。

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

如果 Django 正在做这些事情,为什么?是否内存不足,线程不足,是否有某种原因会限制线程数等?

作为对周末临时修复的盲目尝试,我建立了应用程序的第二个实例,并将 Nginx 配置为循环负载平衡。它似乎奏效了,但直到星期一早上出现高峰负载时我才能确定。

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

除了“投入更多资源”之外,我真的想在这里学习一些有值(value)的东西!

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

更新

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

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

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

更新 2

潜在的问题(正如我周一早上进入时一位精通 Linux 内核的同事所描述的那样)是 LISTEN QUEUE DEPTH。

正是这种结构的能力受到限制。当一个进程监听一个端口并且新的连接尝试进入(在建立连接之前)时,如果进程建立连接的速度比它们进入的速度慢,那么 LISTEN QUEUE 就会建立起来。

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

我绝不是这方面的专家,但正是我所追求的这个结构,为什么给定的进程突然决定(或操作系统决定)它不会接受更多的连接。

更多可阅读here .

再次感谢 Philipp 带领我走上正确的道路!

最佳答案

upstream prematurely closed connection while reading response header from upstream



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

根据您的描述,可能是 Python 服务器无法并行处理足够多的请求并阻塞。只要你前面没有Nginx,你就不会注意到,也许只是请求很慢。有了 Nginx,它就会发生变化,因为 Nginx 可以轻松处理大量请求,并且可能会接受比其上游服务器(即您的 Python 服务器)可以跟上的更多请求。在这种情况下,上游服务器没有响应,最终套接字被关闭,这迫使 Nginx 以 502(错误网关)失败。

为了测试该理论,您比较了向 Nginx 或直接向 Python 服务器发出多个请求时发生的情况。当您直接转到 Python 服务器时,它的请求会被阻止并且服务速度较慢(但没有错误),但是当您转到 Nginx 时,所有请求都会立即被接受(但有些会以 502 失败),这可能就是我所描述的情况。

在这种情况下,您可以尝试以下几点:
  • 确保 keep-alive 在 Nginx 上工作(无论如何这是一个好主意,并且应该限制对上游的并行请求的数量)。详情见this answer .
  • (如果可能)更改 Python 服务器,以便它们可以处理更多并行请求
  • 确保服务器上的文件句柄没有用完,并监视系统上的 TPC 套接字数量(例如,使用 sudo netstat -tulpan )。

  • 我可能是错的,因为我在答案中做了很多猜测。不过,我希望它能给您一些解决请求关闭(或超时)原因的想法。

    关于django - Nginx 反向代理到 Django 接收 `upstream prematurely closed connection while reading response header from upstream`,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59002581/

    31 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com