Nginx、Django和Gunicorn。Gunicorn套接字文件丢失?

16
我有一个使用Ansible配置的虚拟机,基于此链接的代码https://github.com/jcalazan/ansible-django-stack,但是尝试启动Gunicorn时出现以下错误:

无法连接到/path/to/my/gunicorn.sock

在nginx日志文件中:

连接unix:/path/to/my/gunicorn.sock失败(2: No such file or directory),同时连接到upstream

实际上,在指定目录中缺少套接字文件。我已检查了目录的权限,它们是正常的。

这是我的gunicorn_start脚本:

NAME="{{ application_name }}"
DJANGODIR={{ application_path }}
SOCKFILE={{ virtualenv_path }}/run/gunicorn.sock
USER={{ gunicorn_user }}
GROUP={{ gunicorn_group }}
NUM_WORKERS={{ gunicorn_num_workers }}

# Set this to 0 for unlimited requests. During development, you might want to
# set this to 1 to automatically restart the process on each request (i.e. your
# code will be reloaded on every request).
MAX_REQUESTS={{ gunicorn_max_requests }}

echo "Starting $NAME as `whoami`"

# Activate the virtual environment.
cd $DJANGODIR
. ../../bin/activate

# Set additional environment variables.
. ../../bin/postactivate

# Create the run directory if it doesn't exist.
RUNDIR=$(dirname $SOCKFILE)
test -d $RUNDIR || mkdir -p $RUNDIR

# Programs meant to be run under supervisor should not daemonize themselves
# (do not use --daemon).
exec gunicorn \
    --name $NAME \
    --workers $NUM_WORKERS \
    --max-requests $MAX_REQUESTS \
    --user $USER --group $GROUP \
    --log-level debug \
    --bind unix:$SOCKFILE \
    {{ application_name }}.wsgi

有没有人能提供其他可能导致Socket文件丢失的建议?
谢谢。
5个回答

27

嗯,由于我的声望不足以发表评论,我想在这里提及一下,缺少套接字并没有给出很多具体信息,但是我可以告诉你一些关于如何像你现在这样入门并让事情正常工作的方法。

长话短说,当gunicorn被upstart启动时遇到问题,要么始终无法启动,要么关闭了。以下是一些可能有助于获得更多信息以跟踪问题的步骤:

  • 在我的情况下,当发生这种情况时,gunicorn从未进行任何错误日志记录,因此我必须寻找其他地方。尝试使用 ps auxf | grep gunicorn 查看是否有任何工作程序正在运行。我没有。
  • 查看upstart在syslog中的投诉,grep init: /var/log/syslog,显示我的gunicorn服务已停止,因为它重新启动太快,尽管我怀疑这不会是您的问题,因为您的conf中没有重新启动。不管怎样,您可能会在那里找到一些东西。
  • 在看到gunicorn无法运行或记录错误后,我决定尝试从命令行运行它。转到您的manage.py所在的目录,并针对您的gunicorn实例运行扩展版本的upstart命令。类似于(用适当的literals替换所有变量而不是我使用的垃圾):
  • /path/to/your/virtualenv/bin/gunicorn --name myapp --workers 4 --max-requests 10 --user appuser --group webusers --log-level debug --error-logfile /somewhere/I/can/find/error.log --bind unix:/tmp/myapp.socket myapp.wsgi

  • 如果您很幸运,可能会得到Python traceback或在手动运行命令后在gunicorn错误日志中找到一些内容。有些问题可能会出现:

    • Django错误(也许是加载设置模块的问题?)。确保wsgi.py在服务器上引用适当的设置模块。
    • upstart脚本中的空格问题。我有一个隐藏在空格中的制表符,这使事情变得混乱了。
    • 用户/权限问题。最终,我能够在命令行上以root身份运行gunicorn,但不能通过upstart配置作为非root用户运行。

希望这有所帮助。我花了几个漫长的日子来跟踪这些问题。


哦,忘了提醒你在命令行中使用--daemon(但不要在upstart配置文件中使用)以便在运行时检查日志和其他信息。 - swendr
我尝试了上述步骤,但不幸的是没有找到任何东西。没有其他gunicorn进程在运行,syslog中也没有任何内容。然后我找到了问题所在。我尝试更改sockfile目录,从/webapps/my-app/run/gunicorn-sock更改为/sockets/gunicorn.sock,这样就可以了。但我不知道旧目录有什么问题,因为它具有777权限,启动gunicorn的用户也是所有者。 - kalo
啊,对不起。我以为你在使用upstart,而不是supervisord。我认为supervisord有它自己的活动日志,可能会给你更多信息。 - swendr
一个非常好的调试建议(我希望我更经常记得):尝试在终端中运行exec命令。 - Raiyan
为了解决这个问题,我不得不执行 chmod 777 /env/bin/gunicorn 和 /env/bin/python。 - Frumples

9
我在按照Michal Karzynski的指南 '使用Nginx、Gunicorn、virtualenv、supervisor和PostgreSQL设置Django' 后遇到了同样的问题。

下面是我的解决方法。

我在启动通过Supervisor启动gunicorn的bash脚本(myapp/bin/gunicorn_start)中有这个变量:

SOCKFILE={{ myapp absolute path }}/run/gunicorn.sock

当你第一次运行bash脚本时,它将使用root权限创建一个名为“run”的文件夹和一个sock文件。所以我用sudo删除了run文件夹,然后再没有sudo特权的情况下重新创建它,然后就完成了!现在如果你重新运行Gunicorn或Supervisor,你就不会再收到烦人的缺少sock文件的错误消息了!
TL;DR: 1. 用sudo删除run文件夹。 2. 不使用sudo特权重新创建该文件夹。 3. 再次运行Gunicorn。 4. ???? 5. 利润增加。

4
错误也可能是由于您没有安装需要的pip依赖项而引起的。在我的情况下,通过查看gunicorn错误日志,我发现缺少了一个模块。通常发生在忘记pip安装新需求时。

1

嗯,我为这个问题工作了一个多星期,最终终于找到了解决方法。 请访问digital ocean链接,但它们没有指出重要的问题,其中包括:

  1. 连接到上游时没有活动上游
  2. *4 连接到 unix:/myproject.sock 失败(13: Permission denied),同时连接到上游
  3. gunicorn OSError:[Errno 1] 操作不允许
  4. *1 连接到 unix:/tmp/myproject.sock 失败(2: No such file or directory)

    等等。

这些问题基本上是 Nginx 和 Gunicorn 之间连接的权限问题。 为了简化事情,我建议给每个文件/项目/Python 程序相同的 nginx 权限

为了解决所有问题,请按照以下步骤进行:

  1. 以root用户身份登录系统
  2. 创建/home/nginx目录。
  3. 完成后,请按照网站的指导直到创建Upstart脚本。
  4. 运行 chown -R nginx:nginx /home/nginx
  5. 对于Upstart脚本,在最后一行进行以下更改: exec gunicorn --workers 3 --bind unix:myproject.sock -u nginx -g nginx wsgi 不要添加-m权限,因为它会破坏套接字。根据Gunicorn的文档,当-m是默认值时,Python会找出最佳权限。
  6. 启动Upstart脚本
  7. 现在只需进入/etc/nginx/nginx.conf文件。 进入服务器模块并附加:

    location / { include proxy_params; proxy_pass http://unix:/home/nginx/myproject.sock; } 删除<> 从这里开始不要再遵循digitalocean文章

    1. 现在重新启动nginx服务器,您就可以开始使用了。

1

我曾经遇到同样的问题,后来发现我在gunicorn脚本中设置了DJANGO_SETTINGS_MODULE为生产环境设置,而wsgi设置使用的是开发环境。

我将DJANGO_SETTINGS_MODULE指向dev,一切都正常了。


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