uwsgi + nginx + flask:上游过早关闭
Posted
技术标签:
【中文标题】uwsgi + nginx + flask:上游过早关闭【英文标题】:uwsgi + nginx + flask: upstream prematurely closed 【发布时间】:2015-02-08 08:47:53 【问题描述】:我在我的烧瓶上创建了一个端点,它从数据库查询(远程数据库)生成电子表格,然后将其作为下载发送到浏览器中。 Flask 不会抛出任何错误。 Uwsgi 没有抱怨。
但是当我检查 nginx 的 error.log 时,我看到了很多
2014/12/10 05:06:24 [错误] 14084#0: *239436 过早上游 从上游读取响应标头时关闭连接,客户端: 34.34.34.34,服务器:me.com,请求:“GET /download/export.csv HTTP/1.1”,上游:“uwsgi://0.0.0.0:5002”,主机:“me.com”,推荐人: "https://me.com/download/export.csv"
我像部署uwsgi
uwsgi --socket 0.0.0.0:5002 --buffer-size=32768 --module server --callab app
我的 nginx 配置:
server
listen 80;
merge_slashes off;
server_name me.com www.me.cpm;
location / try_files $uri @app;
location @app
include uwsgi_params;
uwsgi_pass 0.0.0.0:5002;
uwsgi_buffer_size 32k;
uwsgi_buffers 8 32k;
uwsgi_busy_buffers_size 32k;
server
listen 443;
merge_slashes off;
server_name me.com www.me.com;
location / try_files $uri @app;
location @app
include uwsgi_params;
uwsgi_pass 0.0.0.0:5002;
uwsgi_buffer_size 32k;
uwsgi_buffers 8 32k;
uwsgi_busy_buffers_size 32k;
这是 nginx 或 uwsgi 问题,还是两者兼而有之?
【问题讨论】:
我曾经遇到过同样的错误,原来是我忘记了“include uwsgi_params”。或者检查你的uwsgi_params
nginx confs 下的文件
【参考方案1】:
正如@mahdix 所述,错误可能是由于 Nginx 使用 uwsgi 协议发送请求,而 uwsgi 正在该端口上侦听 http 数据包。
在 Nginx 配置中,你有类似的东西:
upstream org_app
server 10.0.9.79:9597;
location /
include uwsgi_params;
uwsgi_pass org_app;
Nginx 将使用 uwsgi 协议。但是如果在uwsgi.ini
中你有类似的东西(或在命令行中的等价物):
http-socket=:9597
uwsgi 会speak http,出现问题中提到的错误。见native HTTP support。
一个可能的解决方法是:
socket=:9597
在这种情况下,Nginx 和 uwsgi 将通过 TCP 连接使用 uwsgi 协议相互通信。
旁注:如果 Nginx 和 uwsgi 在同一个节点中,则 Unix 套接字将比 TCP 快。见using Unix sockets instead of ports。
【讨论】:
【参考方案2】:更改 nginx.conf 以包含
sendfile on;
client_max_body_size 20M;
keepalive_timeout 0;
完整示例见自我回答uwsgi upstart on amazon linux
【讨论】:
【参考方案3】:在我的情况下,问题是 nginx 正在使用 uwsgi 协议发送请求,而 uwsgi 正在该端口上侦听 http 数据包。所以要么我不得不改变 nginx 连接到 uwsgi 的方式,要么改变 uwsgi 以使用 uwsgi 协议进行监听。
【讨论】:
您能否将解决方案的详细信息添加到您的答案中?我相信您要么需要使用uwsgi_pass
,然后将socket
值设置为uwsgi .ini 文件中的端口,要么在nginx 中设置proxy_pass
,同时将http-socket
设置为uwsgi 中的端口?【参考方案4】:
我在 Elastic Beanstalk 单容器 Docker WSGI 应用程序部署中遇到了同样的零星错误。在环境上游配置的 EC2 实例上如下所示:
upstream docker
server 172.17.0.3:8080;
keepalive 256;
使用这个默认的上游简单负载测试,例如:
siege -b -c 16 -t 60S -T 'application/json' 'http://host/foo POST "foo": "bar"'
...在 EC2 上导致约 70% 的可用性。其余的是 从上游读取响应标头时上游过早关闭连接导致的 502 错误。
解决方案是从上游配置中删除keepalive
设置,或者更简单、更合理的方法是在uWSGI
一侧启用HTTP keep-alive,以及--http-keepalive
(@987654321 @)。
【讨论】:
【参考方案5】:将uwsgi_pass 0.0.0.0:5002;
替换为uwsgi_pass 127.0.0.1:5002;
或更好地使用unix 套接字。
【讨论】:
【参考方案6】:似乎有很多原因可以支持此错误消息。我知道您使用的是uwsgi_pass
,但对于那些在使用proxy_pass
时遇到长请求问题的人,在uWSGI 上设置http-timeout
可能会有所帮助(这不是harakiri 设置)。
【讨论】:
【参考方案7】:我通过在 uwsgi 中传递 socket-timeout = 65
(uwsgi.ini 文件)或 --socket-timeout=65
(uwsgi 命令行)选项解决了这个问题。我们必须检查不同的值取决于网络流量。 uwsgi.ini 文件中的这个值socket-timeout = 65
在我的情况下有效。
【讨论】:
【参考方案8】:这个问题有很多潜在的原因和解决方案。就我而言,后端代码运行时间过长。修改这些变量为我修复了它。
Nginx:
proxy_connect_timeout
、proxy_send_timeout
、proxy_read_timeout
、fastcgi_send_timeout
、fastcgi_read_timeout
、keepalive_timeout
、uwsgi_read_timeout
、uwsgi_send_timeout
、uwsgi_socket_keepalive
。
uWSGI:limit-post
.
【讨论】:
【参考方案9】:我通过恢复为 pip3 install uwsgi
来解决此问题。
我正在尝试同时使用 Ubuntu 和 Amazon Linux 进行设置。我最初使用虚拟环境并且pip3 install uwsgi
两个系统都工作正常。后来,我确实在关闭虚拟环境的情况下继续设置。在 Ubuntu 上,我使用 pip3 install uwsgi
安装,在 Amazon Linux 上使用 yum install uwsgi -y
。这就是我问题的根源。
Ubuntu 运行良好,但 Amazon Linux 不行
修复,
yum remove uwsgi
和 pip3 install uwsgi
重新启动,它工作正常。
【讨论】:
以上是关于uwsgi + nginx + flask:上游过早关闭的主要内容,如果未能解决你的问题,请参考以下文章
错误:从上游 [uWSGI/Django/NGINX] 读取响应标头时,上游过早关闭连接