Nginx是否给uWSGI很旧的请求?

问题描述:

我看到一个奇怪的情况,Nginx或uwsgi似乎正在建立一个长队列的传入请求,并在客户端连接超时后尝试处理它们。我想了解并制止这种行为。下面是详细信息:Nginx是否给uWSGI很旧的请求?

我的设置

我的服务器使用的Nginx通过Unix套接字文件通过HTTPS POST请求uWSGI和瓶。我基本上都是默认配置。

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

的问题

运行客户端,约4小时后,客户机开始报告称,所有的连接都超时。 (它使用7秒超时的Python请求库。)大约10分钟后,行为改变了:连接开始因502 Bad Gateway失败。

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

在这10分钟,每次uwsgi.log条目是这样的:

Thu May 25 07:36:37 2017 - SIGPIPE: writing to a closed pipe/socket/fd (probably the client disconnected) on request /api/polldata (ip 98.210.18.212) !!! Thu May 25 07:36:37 2017 - uwsgi_response_writev_headers_and_body_do(): Broken pipe [core/writer.c line 296] during POST /api/polldata (98.210.18.212) IOError: write error [pid: 34|app: 0|req: 645/12472] 98.210.18.212() {42 vars in 588 bytes} [Thu May 25 07:36:08 2017] POST /api/polldata => generated 0 bytes in 28345 msecs (HTTP/1.1 200) 2 headers in 0 bytes (0 switches on core 0)

而且Nginx的error.log显示了很多这样的:

2017/05/25 08:10:29 [error] 36#36: *35037 connect() to unix:/srv/my_server/myproject.sock failed (11: Resource temporarily unavailable) while connecting to upstream, client: 98.210.18.212, server: example.com, request: "POST /api/polldata HTTP/1.1", upstream: "uwsgi://unix:/srv/my_server/myproject.sock:", host: "example.com:5000"

约10分钟uWSGI后活动停止。当我重新打开客户端时,Nginx很高兴地接受了POST请求,但是uWSGI在每次请求时都给出了“写入一个关闭的管道”的错误,就好像它永久地被破坏了一样。重新启动Web服务器的docker容器并不能解决问题,但重新启动主机会修复它。

理论

在默认的Nginx - >插座 - > uWSGI配置,有没有超时请求的长龙?我查看了uWSGI文档,并且看到了一些可配置的超时时间,但所有缺省时间都在60秒左右,所以我无法理解我如何处理10分钟的请求。我没有更改任何默认超时设置。

该应用程序在我的小型开发服务器中使用几乎所有的1GB RAM,所以我认为资源限制可能会触发该行为。

无论哪种方式,我想改变我的配置,使得> 30秒的请求丢失500错误,而不是由uWSGI处理。我很感激任何关于如何做到这一点的建议,以及关于发生了什么的理论。

这似乎是uWSGI方面的下游问题。

这听起来像您的后端代码可能有错误,因为它takes too long处理请求,没有实现任何类型的速率限制的请求,并没有正确捕获任何基础连接已终止(因此,您收到代码尝试写入封闭管道的错误,甚至可能在底层连接终止很久后开始处理新的请求)。

+1

谢谢;这些解释是有道理的 - 基本上nginx正在向uwsgi的socket填充请求,而忽略了uwsgi没有处理它们的事实。奇怪的是,默认配置允许;我会认为uwsgi至少会根据传入请求在套接字中的位置有多长时间。 'ignore_client_abort'设置很有趣;我会尝试的。 (harakiri设置没有解决它。) – Luke

+0

@Luke,是的,我认为,基本上,uWSGI做出了一个保守的假设,即使客户立即断开连接,您可能不希望有任何请求丢失;看起来您至少可能需要修改后端,至少在您开始处理请求时检查客户端是否仍处于连接状态。此外,相关的,关于删除完整的晚期请求的有趣阅读 - http://ferd.ca/rtb-where-erlang-blooms.html – cnst

好像是对Nginx uWSGI的DoS攻击,使用Nginx 502,504,500返回100%CPU使用率.IP欺骗在DoS攻击中很常见。通过检查日志排​​除。