由于上游连接重置,Nginx 产生 499 状态

由于上游连接重置,Nginx 产生 499 状态

已阅读其他帖子;它们没有提供太多启示。

情况:

  • Kubernetes 集群的入口点为
  • 几个 nginx 容器通过代理传递到
  • 通过位置 /app/ 指向特定 URI 的 Node 应用程序

我们看到的情况:

经过几天无故障的工作后,相同的当所有 3 个 nginx 容器开始向节点应用程序报告上游问题时 - 该连接被客户端意外关闭。

但是,通过直接进入节点应用程序(直接入口路由),甚至从 nginx 容器进行 curling,成功率可达 100%。也就是说,该问题似乎并不存在于应用程序本身,或者我们预计会看到类似的失败率,原因与通过 nginx 相同。

  • CPU - 远低于最大值
  • 内存 - 远低于最大值
  • 配置了 1024 个套接字
  • 100k 文件描述符(硬限制和软限制)。

这就是我所知道的全部内容,但这是一个紧迫的问题,目前尚不清楚问题是什么,或者为什么直接执行会产生如此不同的行为。此外,为什么通过 docker exec 访问 nginx 容器并从那里进行 curl 不会产生问题?

目前的假设是某种形式的资源已经枯竭,但目前尚不清楚该资源是什么。

我们没有维持保持活动状态,但如果问题在于套接字/端口耗尽,那么我们在直接登录容器时肯定会看到相同的行为。

我开始想不出主意了——所以任何帮助我都非常感谢。
现在,我有一个定时炸弹;几天来服务都很完美,然后突然——砰!客户端 30% 的时间经历了 120 秒或 60 秒的延迟(请求似乎在第一次失败时从一个 nginx 转移到另一个 nginx)。

最后 - 重新启动容器:问题消失。
好吧,直到它再次出现,几天后有时是几周后。因此,这就是为什么我们不认为这是节点应用程序本身的问题;
如果它是节点应用程序,为什么直接命中它会 100% 的时间有效,重新启动 nginx 容器/nginx 重新加载(进程保持活动状态,但新的工作进程发出新的配置更改)如何解决节点的问题?

因此,我们认为问题出在 nginx 上 - 但具体在哪里还不清楚。重启后与重启前相比,资源似乎没有太大不同 - 但事实上,重启可以完全解决问题,问题需要几天时间才会出现,我们认为这与资源有关。不过,无法就该资源是什么提出合理的建议。

答案1

499 错误是客户端特有的,似乎与 Nginx 无关。这意味着后端(您的节点应用程序)正在关闭连接,而 nginx 仍在处理请求。

基本的 curl 命令无法重现相同的错误。要重现该错误,请在入口开始报告 499 错误时查看应用程序日志,并使用 curl 命令重现该错误。如果您发现任何特定端点花费的时间比预期的要长,请尝试使用 curl/postman 复制该端点,并注意处理请求需要多长时间,这将为您提供一个很好的起点来调整server.timeout该特定请求的最大执行时间(或在 NodeJS 中)。

答案2

我希望你们已经找到了这个问题的解决方案,因为我们在设置中也遇到了完全相同的行为。我相信 Nginx 反向代理后面是什么应用程序或 Web 服务器并不重要。在上游,我们有 Apache、Kestrel、Nginx、HAProxy 等 Web 服务器,以及包括 dotnet、PHP、Python 和 Node.js 在内的各种应用程序。

我们进行了一些监控,发现当 nf_conntrack_count 中当前分配的流条目数快速增加时,该特定主机上的平均负载也会增加,并且 Nginx 反向代理日志中的 http 499 错误数量也会增加。此外,当 nf_conntrack_count 中当前分配的流条目数减少时,错误数量也会减少。

但是,我不想责怪任何具体的事情,因为我还没有找到解决这个问题的方法。我希望这些信息有助于产生一些想法。我真的很期待更多的人加入进来,帮助解决这个问题。

相关内容