Li Shen Blog

Stay hungry, stay foolish.

django+daphne+nginx部署(http和ws)

沈大力

写之前我想先发泄一句:太~不~容~易~了!

主要我后台运维的知识几乎为0,也就当时为了用NGINX+UWSGI部署django现学了一点点,导致这次遇到问题费了三天才解决。

...

那么,开始教程吧!

 

1. 部署前:

部署前的工作十分的重要,主要分为两点:

①. 你的websocket程序能不能跑的通。这里不只是说在你自己电脑上能跑通就行,你把东西放到服务器上后,通过django的runserver命令看看能不能顺利的实现你的websocket功能。如果可以的话再往下走。

②. 理清思路。可参考下图:

如果我们的网站没有websocket服务,那我们只要打通NGINX→UWSGI→Django这样一条通路即可。所以这里我们需要实现的就是NGINX→Daphne(asgi)→Django这条通路。

 

2. 工具安装:

我们首先安装所需要的一些工具:Daphne,supervisor,django的channels库。

apt-get install daphne
apt-get install supervisor
pip install channels

Daphne: uwsgi并不能处理websocket请求,所以需要asgi服务器来处理websocket请求,官方推荐的asgi服务器是daphne,也可使用uvicorn,部署方式类似。关于wsgi,asgi的相关知识可参考:WSGI & ASGI

 

supervisor:进程管理工具,会让我们的部署更方便,也更稳定,具体可参考:supervisor(一)基础篇

 

channels:django处理websocket依赖的库。

 

3. Daphne配置:

我们首先在你项目的settings.py所在的文件夹中创建asgi.py,然后写入:

import os
import django
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "你项目的名字.settings")
django.setup()
application = get_default_application()

写入完成后,可以执行daphne来测试一下:

daphne -b 0.0.0.0 -p 8001 你项目的名字.asgi:application

没有报错我们就可接着下一步配置supervisor。

 

4. supervisor配置:

首先生成supervisor的配置文件:

echo_supervisord_conf > /etc/supervisor/supervisord.conf

在生成的supervisord.conf中添加配置(注意:该配置文件默认有很多参数,在这里我们不需要做改动,如果想要个性化设置,可以参考上面supervisor介绍中的参数说明进行改动。):

[program:daphne]
directory=你项目的绝对路径
command=daphne -b 0.0.0.0 -p 8001 你项目的名字.asgi:application
autostart=true
autorestart=true
stdout_logfile=/tmp/websocket.log  #生成日志的路径(自行更改)
redirect_stderr=true

同样地,我们也可以测试一下:

supervisord -c /etc/supervisor/supervisord.conf

 

5. NGINX配置:

NGINX文件中我们不需要改动uwsgi的相关配置,只需要加入:

###将websocket请求转发到我们指定的8001端口
upstream wsbackend {
         server 127.0.0.1:8001;
}

###然后添加location配置

 location /websocket {
        proxy_pass http://wsbackend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Host $server_name;
  }

我没有去详细了解location内每行参数的意思,只需要知道这里是为了将你websocket的请求转发至你指定的位置端口就行。这里/websocket是我自己设置的,你可以看你routing.py中设置的什么路径,就把/websocket替换成你的路径。例如,我搭建了一个在线聊天的软件,在www.example.com/app/chat中,那么我这里就改为/app/chat。

 

6. 启动/关闭相关服务

启动命令:

service supervisor start && unlink /tmp/supervisor.sock  && supervisord -c /etc/supervisor/supervisord.conf && uwsgi --ini uwsgi.ini && service nginx start

这里先后顺序是:启动supervisor服务→启动supervisord.conf中我们配置的daphne服务→启动uwsgi服务→启动nginx。

关闭命令:

killall -9 uwsgi && service nginx stop && supervisorctl stop daphne && killall -9 supervisord && service supervisor stop

关闭顺序是:关闭uwsgi服务→关闭nginx服务→停止daphne服务→杀死所有supervisord进程→关闭supervisor服务。

 

7. 结尾

这次卡了三天主要原因是卡在两点,第一点是端口混乱,一开始我不清楚为什么不能跟uwsgi服务设置同样的8000端口,换句话说我没有理清楚一开始我画的那张通路图,导致盲人摸象。第二点我对NGINX不熟悉,关于NGINX的location配置我是照着网上的教程写的,然后对方教程在/websocket那里用的他自己设置的/ws,我一开始并不知道那个是自己设定的,导致这里我卡了2天。也是从这个过程,加上之前用NGINX+uwsgi部署也花了很久(虽然之前部署过,由于时间很久,忘光了),我意识到必须把这些过程记录下来,在提供教程的同时,自己也能好好梳理一下其中的技术点,不断吸收学习。

 

最后,各位可以帮我试试我搭建的在线终端平台,由于服务器的原因,应该会有点卡,还请体谅一下。在线终端(由于安全原因我还是把这个功能关掉了。)

745人读过
网站相关 Python Django
Oct. 21, 2020, 8 a.m.

评论:

登录后方可评论,点击登录注册

评论列表:

暂无评论。

苏公网安备 32050602011302号

苏ICP备2020062135号-1
Copyright© Li Shen. All rights reserved.