[英]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.