Nginx正在向uWSGI提交非常旧的请求?

Nginx正在向uWSGI提交非常旧的请求?,nginx,flask,uwsgi,unix-socket,Nginx,Flask,Uwsgi,Unix Socket,我看到了一种奇怪的情况,Nginx或uwsgi似乎正在建立一个长长的传入请求队列,并试图在客户端连接超时很久之后处理它们。我想理解并阻止这种行为。以下是更多信息: 我的设置 我的服务器使用Nginx通过Unix文件套接字将HTTPS POST请求传递给uWSGI和Flask。我基本上所有的东西都有默认配置 我有一个Python客户端每秒向该服务器发送3个请求 问题 在运行客户端大约4小时后,客户端计算机开始报告所有连接都超时。大约10分钟后,行为发生了变化:502坏网关连接开始失败 我关掉了客户

我看到了一种奇怪的情况,Nginx或uwsgi似乎正在建立一个长长的传入请求队列,并试图在客户端连接超时很久之后处理它们。我想理解并阻止这种行为。以下是更多信息:

我的设置

我的服务器使用Nginx通过Unix文件套接字将HTTPS POST请求传递给uWSGI和Flask。我基本上所有的东西都有默认配置

我有一个Python客户端每秒向该服务器发送3个请求

问题

在运行客户端大约4小时后,客户端计算机开始报告所有连接都超时。大约10分钟后,行为发生了变化:502坏网关连接开始失败

我关掉了客户端。但在关闭客户端电源后的大约10分钟内,服务器端uWSGI日志显示uWSGI试图回答来自该客户端的请求!而
top
显示uWSGI使用100%的CPU(每个工人25%)

在这10分钟内,每个
uwsgi.log
条目如下所示:


2017年5月25日星期四07:36:37-SIGPIPE:根据请求/api/polldata(ip 98.210.18.212)写入封闭管道/插座/fd(可能是客户端断开连接)!!!
2017年5月25日星期四07:36:37-uwsgi_响应_writev_headers_和_body_do():POST/api/polldata期间管道破裂[core/writer.c line 296](98.210.18.212)
IOError:写入错误
[pid:34 | app:0 | req:645/12472]98.210.18.212(){588字节中的42个变量}[Thu May 25 07:36:08 2017]POST/api/polldata=>在28345毫秒内生成0字节(HTTP/1.1200)在0字节内生成2个头(核心0上的0个开关)

Nginx
error.log
显示了很多这方面的信息:


2017/05/25 08:10:29[错误]36#36:*35037 connect()到unix:/srv/my#u server/myproject.sock在连接到上游时失败(11:资源暂时不可用),客户端:98.210.18.212,服务器:example.com,请求:“POST/api/polldata HTTP/1.1”,上游:uwsgi://unix:/srv/my_server/myproject.sock:,主机:“example.com:5000”

大约10分钟后,uWSGI活动停止。当我重新打开客户端时,Nginx愉快地接受POST请求,但uWSGI在每个请求上都会出现相同的“向封闭管道写入”错误,就好像它永远被破坏了一样。重新启动Web服务器的docker容器并不能解决此问题,但重新启动主机可以解决此问题

理论

在默认的Nginx->socket->uWSGI配置中,是否存在没有超时的长请求队列?我查看了uWSGI文档,看到了一系列可配置的超时,但都默认为60秒左右,因此我无法理解如何处理10分钟前的请求。我没有更改任何默认超时设置

该应用程序使用了我的小型开发服务器中几乎所有1GB的RAM,因此我认为资源限制可能触发了这种行为


无论哪种方式,我都希望更改我的配置,以使超过30秒的请求以500个错误被丢弃,而不是由uWSGI处理。如果您能给我一些建议,以及正在发生的事情的理论,我将不胜感激。

似乎是针对Nginx uWSGI的DoS攻击,使用Nginx 5025000返回100%的CPU使用率。IP欺骗在DoS攻击中很常见。通过检查日志排除

这似乎是uWSGI下游的一个问题

听起来您的后端代码可能有问题,因为它无法处理请求,没有对请求实施任何类型的速率限制,并且没有正确捕获任何底层连接是否已终止(因此,您会收到代码试图写入已关闭管道的错误,甚至可能在基础连接终止后很久才开始处理新请求)

  • 根据,如果未连接uwsgi.is\u(uwsgi.connection\u fd()),您可能希望中止后端
    中的处理

  • 你可能想探索一下

  • 作为最后一种手段,根据,您可能希望从
    关闭
    更改为
    打开
    ,以避免断开已传递到上游的正在进行的uWSGI连接(即使客户端随后断开连接)为了不从uWSGI接收封闭管道错误,以及在nginx本身内强制执行任何可能的并发连接限制(否则,如果客户端断开连接,nginx将断开与uWSGI的连接,nginx将不知道uWSGI内有多少请求排队等待后续处理)


谢谢;这些解释是有道理的——基本上nginx用请求填充uwsgi的套接字,忽略了uwsgi没有处理它们的事实。奇怪的是,默认配置允许这样做;我本以为uwsgi至少会有一个超时,这取决于传入请求在套接字中停留的时间。
ignore_client_abort
设置很有趣,我会试试。(harakiri设置没有解决这个问题。)@Luke,是的,我认为,基本上,uWSGI做出了一个保守的假设,即即使客户端立即断开连接,您也可能不希望丢弃任何请求;看起来,至少,您可能希望修改您的后端,至少在您开始处理请求时检查客户端是否仍然连接。另外,这是一篇有趣的阅读,内容是关于完全删除延迟请求-