我看到一种奇怪的情况,其中Nginx或uwsgi似乎正在建立一个长队列的传入请求,并试图在客户端连接超时后很久处理它们。我想了解并停止这种行为。以下是更多信息:
我的设置
我的服务器使用Nginx通过Unix文件套接字将HTTPS POST请求传递给uWSGI和Flask。我基本上都有默认配置。
我有一个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处理。我很欣赏有关如何做到这一点的任何建议,以及有关正在发生的事情的理论。
答案 0 :(得分:1)
这似乎是uWSGI方面的下游问题。
听起来你的后端代码可能有问题,因为它takes too long处理请求,没有对请求实施任何类型的速率限制,并且如果任何底层连接没有正确捕获终止(因此,您将收到代码尝试写入已关闭管道的错误,甚至可能在基础连接终止后很久就开始处理新请求)。
根据http://lists.unbit.it/pipermail/uwsgi/2013-February/005362.html,您可能希望在后端if not uwsgi.is_connected(uwsgi.connection_fd())
中止处理。
您可能想要探索https://uwsgi-docs.readthedocs.io/en/latest/Options.html#harakiri。
最后,根据Re: Understanding "proxy_ignore_client_abort" functionality (2014),您可能希望将uwsgi_ignore_client_abort
从off
更改为on
,以便不会丢弃正在进行的uWSGI连接已经传递到上游(即使客户端随后断开连接),以便不从uWSGI接收关闭的管道错误,以及在nginx本身内强制执行任何可能的并发连接限制(否则,与uWSGI的连接将获得如果客户端断开连接,nginx会丢弃,并且nginx将不知道在uWSGI中有多少请求在排队等待后续处理。)
答案 1 :(得分:0)
似乎对Nginx uWSGI的DoS攻击使用Nginx 502,504,500返回100%的CPU使用率.IP欺骗在DoS攻击中很常见。通过检查日志排除。