【问题标题】:Django + gunicorn + nginx: 502 bad gateway but sometimes only?Django + gunicorn + nginx:502 bad gateway,但有时只有?
【发布时间】:2019-01-22 19:31:56
【问题描述】:

我最近决定放弃 apache2 + mod_wsgi 并尝试使用 gunicorn + nginx 来运行我的 Django 应用程序。

在干净的 Ubuntu 16.04 安装上,我完全按照这些教程进行操作:

我以为一切都会好起来的,但是在浏览我的网站时,我注意到有时有几个页面根本没有显示,只是显示502 Bad Gateway 错误。查看error/var/log/nginx/error.log,我只有以下错误:

upstream prematurely closed connection while reading response header from upstream

我不知道这意味着什么:

  • 如果我在 localhost 上运行时没有问题,为什么要安装 Django?
  • 另外:有时所有页面都能正常工作和显示;有时相同的页面会抛出 502 错误:(
  • 如果问题来自那里,我怎么知道我的 gunicorn 安装出了什么问题?如何调试?

供您参考:


/etc/systemd/system/gunicorn.socket

[Unit]
Description=gunicorn socket

[Socket]
ListenStream=/run/gunicorn.sock

[Install]
WantedBy=sockets.target

/etc/systemd/system/gunicorn.service

[Unit]
Description=gunicorn daemon
Requires=gunicorn.socket
After=network.target

[Service]
User=myself
Group=www-data
WorkingDirectory=/home/myself/django/myproject
ExecStart=/home/myself/django/myproject/venvprod/bin/gunicorn \
          --access-logfile - \
          --bind unix:/run/gunicorn.sock \
          myproject.wsgi:application

[Install]
WantedBy=multi-user.target

/etc/nginx/sites-enabled/myproject

server {
    server_name mysite.fr mysite.com;
    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /home/myself/django/myproject;
    }

    location / {
        include proxy_params;
        proxy_pass http://unix:/run/gunicorn.sock;
    }

    listen 443 ssl; # managed by Certbot
    ssl_certificate /etc/letsencrypt/live/mysite.fr/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/mysite.fr/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = mysite.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    if ($host = mysite.fr) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name mysite.fr mysite.com;
    return 404; # managed by Certbot
}

如果还有什么需要,请尽管问!我真正的问题是我不知道如何找到问题。我可以使用什么工具?

提前感谢您的帮助。


编辑 1

我可以确认我的 Django 代码没有任何错误。我将所有内容记录如下:

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'file': {
            'level': 'DEBUG',
            'class': 'logging.FileHandler',
            'filename': '/home/krazymax/debug-m2g.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['file'],
            'level': 'DEBUG',
            'propagate': True,
        },
        'django.template': {
            'handlers': ['file'],
            'level': 'INFO',
            'propagate': True,
        },
    },
}

并且我在浏览我的网站时登录时没有任何错误(页面始终显示,其他页面从不显示,有些有时显示,有时不显示)。


编辑 2

我尝试关注this tutorial,即不使用中间 sock 文件。没有成功,即使在执行 myvenv/bin/gunicorn -c myvenvprod/gunicorn_config.py myproject.wsgi 时我能够访问我的网站(否则不能):我的页面仍然随机显示(或不显示)。我真的不知道,这是官方的,这种随机行为让我发疯!

【问题讨论】:

    标签: django nginx gunicorn


    【解决方案1】:

    这个错误通常表示Nginx和Gunicorn之间没有“连接”,问题出在socket文件上。

    运行“/home/myself/django/myproject/venvprod/bin/gunicorn myproject.wsgi -b 0.0.0.0:8000”并查看输出。 这将使用您的 Django 进程执行 gunicorn 服务器,而不会将其妖魔化。

    您的 Django 代码中可能存在错误,并且未正确创建套接字。 虽然 Gunicorn 已打开,但也尝试从您的浏览器访问 YOUR_IP:8888(例如 52.45.241.21:8888):您看到该网站了吗?

    如果您看到一些 Python 错误,您应该首先使用“manage.py runserver 0.0.0.0:8000”调试您的项目。

    runserver 后的 0.0.0.0:8000 允许从外部浏览器访问您的站点(如 Gunicorn 中的 -b 0.0.0.0:8000 选项)

    记住:在遵循任何关于 Django 项目部署的教程之前,请检查项目是否在使用 runserver 的机器上正常工作

    编辑:也可以试试这样更简单的教程:https://gist.github.com/ravidsrk/8431321

    希望这能帮到你! :)

    【讨论】:

    • 感谢您的回答。我在 Django 中并不陌生,因为我已经在我的应用程序上工作了一年。所以,我对runserveretc 非常熟悉。真正的问题是在部署我的应用程序时:我在本地机器上使用 runserver 运行它没有问题(没有错误),但在我的服务器上运行时出现502 错误。除了upstream prematurely closed connection while reading response header from upstream 之外,日志中的任何内容目前都无法帮助我。
    • @KrazyMax 我很确定问题出在套接字文件上,尝试使用像 127.0.0.1:8001 这样的端口而不是套接字文件,就像在链接的教程中一样。也许 www-data 用户没有读取套接字文件夹的权限
    • 我想尝试,但我不知道如何在我的远程服务器上?看起来您的教程是为本地开发人员制作的,而不是为产品开发人员制作的。什么都没有真正解释,我不明白为什么这样的 IP 是这样绑定的等等。我很难将它应用到我的生产环境中!
    • 可能有一些关于权限的问题,但真正奇怪的是,完全相同的页面有时会正确显示,有时则不会(出现错误 502)。从那以后,我很难相信这个问题来自我的 Django 代码!它应该总是有效,或者永远不会有效,但为什么会出现这种混合行为?! :(
    • 教程是针对Debian/Ubuntu的普通VPS制作的,类似于DigitalOcean的教程。 IP未绑定。唯一的区别是套接字不是 .sock 文件,而是 localhost 端口。 Nginx 和 Gunicorn 不会通信写入/读取 .sock 文件,但会在 localhost 端口上通信(例如 127.0.0.1:8001)
    【解决方案2】:

    我也有同样的问题。我安装 Django、Gunicorn、nginx 请点击此链接:https://www.digitalocean.com/community/tutorials/how-to-set-up-django-with-postgres-nginx-and-gunicorn-on-ubuntu-18-04 有时我的网站变慢并出现 502 错误。尤其是在闲置一段时间并卷土重来的时候。先点击get 502,然后点击两次网站运行流畅。 我创立了这个:https://www.datadoghq.com/blog/nginx-502-bad-gateway-errors-gunicorn/ 在我的情况下:我增加 gunicorn 和 nginx 超时:

    nginx:

    location / {
            include proxy_params;
            proxy_pass http://unix:/run/gunicorn.sock;
            proxy_connect_timeout 300s;
            proxy_read_timeout 300s;
        }
    

    gunicorn 服务:

    ExecStart=/home/myself/django/myproject/venvprod/bin/gunicorn \
              --access-logfile - \
              --bind unix:/run/gunicorn.sock \
              --timeout 60 \
              myproject.wsgi:application
    

    【讨论】:

    • 这对我不起作用,但我怀疑 nginx、gunicorn 和 postgres 之间可能存在不良交互,因为 gunicorn 如何解释来自 postgres 的上游良性错误。我也可以通过关注超时来修复它,但是,我将 fail_timeout=10000000 添加到上游块的服务器条目中。我在这里详细讨论:github.com/benoitc/gunicorn/issues/2347#issuecomment-670797131
    【解决方案3】:

    经过一千次搜索,我找到了解决问题的方法。

    我在虚拟环境中安装了 gunicorn。我不得不去安装文件夹 /virtual/venv/lib/python3.7/site-packages/gunicorn$ 并修改 config.py 文件,将超​​时时间增加到 3000。

    【讨论】:

      猜你喜欢
      • 2023-03-20
      • 2016-04-20
      • 2016-01-04
      • 2014-04-30
      • 2018-07-01
      • 2016-03-26
      • 2020-09-01
      • 2020-06-12
      • 2018-08-03
      相关资源
      最近更新 更多