django-channels+daphne+websocket+supervisor+nginx服务器部署上线

2022年10月18日 17:42 ry 983

这几天给django搭建的网站加了个用户通信和消息推送功能,本地运行完全没有任何问题,部署到服务器时折腾了很久,使用的框架是django,nginx,dphne等,django有个处理websocket的模块,django-channles,我们可以pip install xxx命令进行下载,服务器上下载环境命令如下所示

pip3 install django==2.2.4
pip3 install supervisor
pip3 install redis
pip3 install channels==2.4.0#(里面包含了daphne)
pip3 install channels-redis==2.4.2
pip3 install django-redis==5.2.0

这里注意下,下载channels时也会下载daphne了,本次使用supervisor来管理daphne,因为websocket通信用到asgi协议,而django默认是wsgi协议,要实现asgi,可以使用daphne服务器处理websocket请求,这里我用supervisor来管理daphne服务进程,让其监控它一直运行

root@VM-8-3-ubuntu:/home/ubuntu# cd /etc/supervisor/
root@VM-8-3-ubuntu:/etc/supervisor# ls
conf.d  supervisord.conf

如上是安装supervisor的默认路径,注意这里,可以看见有conf.d  supervisord.conf2个文件,supervisord.conf这个文件我们一般不动,我们可以进去看下其代码,

[unix_http_server]
file=/var/run/supervisor.sock   ; (the path to the socket file)
chmod=0700                       ; sockef file mode (default 0700)

[supervisord]
logfile=/var/log/supervisor/supervisord.log ; (main log file;default $CWD/supervisord.log)
pidfile=/var/run/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
childlogdir=/var/log/supervisor            ; ('AUTO' child log dir, default $TEMP)

; the below section must remain in the config file for RPC
; (supervisorctl/web interface) to work, additional interfaces may be
; added by defining them in separate rpcinterface: sections
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix:///var/run/supervisor.sock ; use a unix:// URL  for a unix socket

; The [include] section can just contain the "files" setting.  This
; setting can list multiple files (separated by whitespace or
; newlines).  It can also contain wildcards.  The filenames are
; interpreted as relative to this file.  Included files *cannot*
; include files themselves.

[include]
files = /etc/supervisor/conf.d/*.conf

直接看最后一行,supervisord.conf这个会自动读取conf.d里面的文件,因此我们想创建一个配置监控管理进程的文件可以直接从cond.d里面创建,而不用动这个supervisord.conf这个文件。切入conf.d,新建一个daphne.conf,里面配置代码如下

[program:daphne]
directory=/home/ubuntu/django_blogs/myblog
command=daphne -b 127.0.0.1 -p 8888 --proxy-headers myblog.asgi:application
# 在supervisord启动的时候也自动启动;
autostart = true
# 程序异常退出后自动重启;
autorestart = true
user = nobody
# 把stderr重定向到stdout,默认false;
redirect_stderr = true
# 标准日志输出;
stdout_logfile=out-daphne.log
# # 错误日志输出;
stderr_logfile=err-daphne.log
environment=ASPNETCORE__ENVIRONMENT=Production
user=root

注意下pragram后面的daphne和你的daphne.conf名对应起来,不然supervisord.conf找不到要执行的conf,这里的directory是你的django项目路径,command就是启动项目中asgi服务了,127.0.0.1是本机,端口是8888,确保这个端口没有被占用,同时服务器设置了这个端口的白名单,后面的配置就不用解释了。这里注意的是asgi.py是和settings.py同目录下,asgi.py代码如下

import os
import django
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myblog.settings")

django.setup()
import users.routing
from channels.http import AsgiHandler
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
from channels.security.websocket import AllowedHostsOriginValidator

application = ProtocolTypeRouter({
    "http": AsgiHandler,
    # Just HTTP for now. (We can add other protocols later.)
    "websocket": AllowedHostsOriginValidator(
            AuthMiddlewareStack(
                URLRouter(
                    users.routing.websocket_urlpatterns
                )
            )
        ),
})

这里注意的是

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myblog.settings")
django.setup()

必须放到import users.routing之前,否则会报错。配置好了supservisor后,开始启动,命令如下

supervisord -c /etc/supervisor/supervisord.conf

可以查看888端口是否正常运行,如果没有正常运行,查看是否有错误日志,一个一个排查即可。接下来就是配置nginx了,进入nginx配置文件,命令如下

cd /usr/local/nginx/conf/

用vim打开nginx.conf,加入的代码如下所示

 location /wss   {
        proxy_pass http://127.0.0.1:8888;
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;

        proxy_set_header X-Forwarded-Host $server_name;

                         }

由于我的配置了ssl证书,因此用wss协议,如果没有配置的则用ws即可,然后前端配置如下

const websocket = new WebSocket(
        (window.location.protocol == 'https:' ? 'wss://' : 'ws://')
        + window.location.host
            + '/wss/chat/'
            + local_user
            + '/'
    );

注意这里不用加端口,直接域名即可!,经过测试,配置成功!

如果上述代码帮助您很多,可以打赏下以减少服务器的开支吗,万分感谢!

欢迎发表评论~

点击此处登录后即可评论


评论列表
暂时还没有任何评论哦...

赣ICP备2021001574号-1

赣公网安备 36092402000079号