【发布时间】:2017-01-23 00:19:22
【问题描述】:
我正在使用 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 Bad Gateway 错误(而对于其他错误,如 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 容器中运行。
【问题讨论】:
-
谷歌搜索表明 Nginx 错误表明后端出现问题。也许
Job.objects.all()是一个异常大的查询,会导致堆栈中的某些内容中断?如果您使用jobs: []但将jobs查询提取到 Python 列表中,该视图是否有效?如果您使用jobs: dummy_array,其中dummy_array大约与预期的jobs结果一样长? -
请发布您的模板。
标签: python django nginx docker gunicorn