繁体   English   中英

在Gunicorn / NGINX / Django中调试静默失败

[英]Debugging silent failure in Gunicorn/NGINX/Django

我正在使用Gunicorn运行Django项目。 我正在使用Nginx作为反向代理。 在大多数情况下,一切正常,但是有一个Django视图导致Gunicorn静默失败。

下面是问题的详细信息,但首先,这是导致问题的Django视图:

def jobs_all(request):
    if not request.user.is_superuser: raise Http404
    jobs = Job.objects.all().order_by('-date_created')
    return render(request, 'monitor/jobs_all.html', {
        'jobs': jobs,
    })

如果我将'jobs': jobs,更改为'jobs': [], ,则可以。 因此,我认为问题涉及将那些QuerySet结果传递给模板。

浏览器中显示的错误是Nginx的502 Bad Gateway错误。 我的Nginx错误日志显示为:

2017/01/22 05:17:25 [error] 22#0: *26 upstream prematurely closed connection while reading response header from upstream, client: 12.34.56.78, server: www.example.com, request: "GET /monitor/jobs/all/ HTTP/1.1", upstream: "http://127.0.0.1:8000/monitor/jobs/all/", host: "www.example.com", referrer: "https://www.example.com/monitor/"

好的,看来Gunicorn正在超时或以某种方式关闭。 但是我不知道如何。 该错误会在几秒钟内发生,在我的Nginx和Gunicorn配置下这应该不是问题。 我没有看到其他错误消息。

这是我启动Gunicorn的命令:

$ /usr/local/bin/gunicorn -b 127.0.0.1:8000 --keep-alive 43200 -w 4 --log-level=DEBUG mydjangoproject.wsgi --timeout=43200

(在生产中,我通过使用Supervisor调用类似的命令来启动Gunicorn,但是具有不同的日志级别和日志文件的路径。我已经检查了Gunicorn日志;他们对此错误保持沉默。)

我的Nginx配置是:

server {
    listen 443 ssl;
    server_name www.example.com;
    access_log /dev/null;
    error_log /logs/nginx/nginx.error.log;

    ssl_certificate /code/ssl/ssl-bundle.crt;
    ssl_certificate_key /code/ssl/server.key;
    ssl_dhparam /code/ssl/dhparams.pem;

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';

    server_tokens off;

    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
        return 405;
    }

    location /static/ {
        root /;
    }

    # TODO add media directory

    client_max_body_size 100M;

    location / {

        client_body_buffer_size 500K;
        client_max_body_size 100M;
        keepalive_timeout 43200;

        proxy_pass_header Server;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Scheme $scheme;
        proxy_connect_timeout 43200;
        proxy_read_timeout 43200;
        proxy_pass http://127.0.0.1:8000/;
    }
}

我还在我的Django项目中启用了DEBUG=True 运气不好,我仍然会收到Nginx 502错误网关错误(而其他错误,例如404错误,我会按预期看到Django错误页面)。

当我使用--log-level=DEBUG运行Gunicorn时触发此错误时,输出如下所示:

[2017-01-22 05:17:22 +0000] [1042] [DEBUG] 4 workers
[2017-01-22 05:17:23 +0000] [1042] [DEBUG] 4 workers
[2017-01-22 05:17:24 +0000] [1042] [DEBUG] 4 workers
[2017-01-22 05:17:25 +0000] [1042] [DEBUG] 4 workers
[2017-01-22 05:17:25 +0000] [1100] [INFO] Booting worker with pid: 1100
[2017-01-22 05:17:26 +0000] [1042] [DEBUG] 4 workers
[2017-01-22 05:17:26 +0000] [1042] [DEBUG] 4 workers
[2017-01-22 05:17:27 +0000] [1042] [DEBUG] 4 workers
[2017-01-22 05:17:28 +0000] [1042] [DEBUG] 4 workers

看来,处理该请求的工作人员默默地死亡,然后默默地重生。

如果我运行Django开发服务器(使用python manage.py runserver 127.0.0.1:8000 )而不是Gunicorn,则视图运行良好。 因此,这似乎是我的Gunicorn配置问题,而不是我的Python / Django代码问题。

我认为这并不重要,但以防万一:一切都在Docker容器中运行。

问题是系统资源不足。 我在具有512MB RAM的Digital Ocean小滴上运行代码。 当我向问题中提到的Django视图发出请求时,我运行了htop ,并且我发现当Gunicorn工人死亡时,RAM的使用已达到极限。 一旦我升级到具有1GB RAM的Droplet,此问题就消失了。 有趣的是Django开发服务器处理了Gunicorn阻塞的请求。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM