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

29

我的用户正在进行一个通常返回872行结果,需要2.07秒才能在MySQL中运行的查询,但是我目前总是得到502错误。不过,查询结果包含了大量信息(每行都包含很多内容)。有任何想法吗?

使用Django(tastypie Rest API)、Nginx和uWSGI堆栈。

NGINX服务器配置。

# the upstream component nginx needs to connect to
upstream django {
    server unix:///srv/www/poka/app/poka/nginx/poka.sock; # for a file socket
}

# configuration of the server
server {
    # the port your site will be served on
    listen  443;


    # the domain name it will serve for
    server_name xxxx; # substitute your machine's IP address or FQDN
    charset     utf-8;

    # max upload size
    client_max_body_size 750M;   # adjust to taste

    # Finally, send all non-media requests to the Django server.
    location / {
        uwsgi_pass  django;
        include     /srv/www/poka/app/poka/nginx/uwsgi_params; # the uwsgi_params file you installed
    }
}

UWSGI配置

# process-related settings
# master
master          = true
# maximum number of worker processes
processes   = 2
# the socket (use the full path to be safe
socket          = /srv/www/poka/app/poka/nginx/poka.sock
# ... with appropriate permissions - may be needed
chmod-socket    = 666
# clear environment on exit
vacuum          = true

pidfile = /tmp/project-master.pid # create a pidfile
harakiri = 120 # respawn processes taking more than 20 seconds
max-requests = 5000 # respawn processes after serving 5000 requests
daemonize = /var/log/uwsgi/poka.log # background the process & log
log-maxsize = 10000000
#http://uwsgi-docs.readthedocs.org/en/latest/Options.html#post-buffering
post-buffering=1
logto = /var/log/uwsgi/poka.log # background the process & log

1
显而易见的答案是分割数据或增加超时时间。这样做不起作用吗? - jwalker
我在哪里可以增加超时时间?增加 harakiri 并没有帮助... 我将来需要实际分割数据... 但现在我没有时间... - abisson
我猜2.07是秒数?日志里有什么信息吗?直接运行uWSGI HTTP服务器,看看是uWSGI还是nginx出了问题? - jwalker
是的,只需要几秒钟……但问题在于现在的872行对于现在来说还算不上什么……它可能会在不久的将来增长到10,000行。但用户最终需要以某种方式将这10,000行数据传输到他的iPad中。我应该开始考虑分批发送数据吗? - abisson
6个回答

16

这很可能不是一个nginx配置问题。

几乎可以确定的是,后端实际上崩溃了(或者只是终止了连接),而不是提供了一个格式错误的响应。也就是说,错误信息告诉你问题所在,但你正在错误的地方寻找解决办法。

您没有提供足够的信息来让我们确定确切的问题,但是如果我必须猜测:

一般情况下在MySQL中返回872行,并花费2.07运行时间,但是它返回了大量的信息。

它可能在某个地方超时或者耗尽了内存。


现在872行还不算什么……但将来可能会增长到10,000行。但用户最终需要以某种方式将这10,000行数据传输到他的iPad上。我应该开始考虑分批发送数据吗? - abisson
6
不,你应该找出导致后端终止请求的原因。 - Danack
为你提到内存不足点赞。我认为在短期内意识到内存可能成为这种错误流的问题是很困难的。 - Konrad Talik
这就是我的问题所在;我在一个只有1GB RAM的虚拟服务器上运行了一个复杂的请求。将服务器的RAM加倍后,问题得到了解决。 - Obsidian Age

7

我曾经有同样的问题,解决方法是在settings.py中添加我的域名,例如:

ALLOWED_HOSTS = ['.mydomain.com', '127.0.0.1', 'localhost']

同样的问题,我指的是页面无法加载,nginx返回502错误,没有提供任何页面,我也无法使应用程序崩溃。

而nginx日志中包含:

Error: upstream prematurely closed connection while reading response header from upstream

2
在您的@django位置块中,您可以尝试添加一些proxy read和connect timeout属性。例如:
location @django {
   proxy_read_timeout 300;
   proxy_connect_timeout 300;
   proxy_redirect off;

   # proxy header definitions
   ...
   proxy_pass http://django;
}

前三行代码帮助我解决了502 ws错误。 - Ankur Loriya

0
请尝试使用以下 uwsgi 配置文件(uwsgi.ini):
[uwsgi]
 master          = true 
 socket          = /home/ubuntu/uwsgi.sock
 chmod-socket    = 666
 chdir           = /home/ubuntu/project
 wsgi-file       = /home/ubuntu/project/project/wsgi.py
 virtualenv      = /home/ubuntu/virtual
 vacuum          = true
 enable-threads  = true
 daemonize       = /home/ubuntu/logs/uwsgi.log

然后运行uwsgi --ini uwsgi.ini

并更新nginx配置以连接到创建的套接字

server {

   listen 80;
   server_name www.domain.com;



       location /static {
       
       alias /home/ubuntu/project/static;
       }

       location /media {
       
       alias /home/ubuntu/project/media;
       }
       
       location / {
       uwsgi_pass unix:///home/ubuntu/uwsgi.sock;
       include uwsgi_params;

        }

}


0
有时可能是权限问题。请检查项目目录的权限。

0

可能是uwsgi配置问题而不是Nginx的问题。我看到你的uwsgi进程=2和harakiri=120,你尝试逐个更改这些以及其他字段了吗?

我遇到了同样的问题,但不是我的NGINX配置,而是我的UWSGI进程在从客户端向服务器发送JSON时导致超时错误。我将进程设置为5,然后将其更改为1,问题得到解决。对于我的应用程序,我只需要每次运行一个进程。

这是工作的UWSGI配置autoboot ini文件,解决了超时问题,从而解决了502网关问题(上游过早关闭)。

autoboot.ini

#!/bin/bash

[uwsgi]
socket          = /tmp/app.sock

master          = true

chmod-socket    = 660
module          = app.wsgi
chdir           = home/app

close-on-exec = true # Allow linux shell via uWSGI

processes = 1
threads = 2
vacuum = true

die-on-term = true

希望这能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接