写之前我想先发泄一句:太~不~容~易~了!
主要我后台运维的知识几乎为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部署也花了很久(虽然之前部署过,由于时间很久,忘光了),我意识到必须把这些过程记录下来,在提供教程的同时,自己也能好好梳理一下其中的技术点,不断吸收学习。
最后,各位可以帮我试试我搭建的在线终端平台,由于服务器的原因,应该会有点卡,还请体谅一下。在线终端(由于安全原因我还是把这个功能关掉了。)