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_timeoutproxy_send_timeoutproxy_read_timeoutfastcgi_send_timeoutfastcgi_read_timeoutkeepalive_timeoutuwsgi_read_timeoutuwsgi_send_timeoutuwsgi_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 uwsgipip3 install uwsgi 重新启动,它工作正常。

【讨论】:

以上是关于uwsgi + nginx + flask:上游过早关闭的主要内容,如果未能解决你的问题,请参考以下文章

错误:从上游 [uWSGI/Django/NGINX] 读取响应标头时,上游过早关闭连接

Ubuntu18部署uwsgi+flask应用

Flask+uwsgi+Nginx+Ubuntu部署

Flask+uwsgi+Nginx+Ubuntu部署

nginx,uwsgi,DJango,502 当 DEBUG=False,“上游过早关闭连接”

部署flask应用到nginx+uwsgi+linux服务器