django-channels的部署(supervisor+daphne+nginx)
项目中需要一个聊天室的功能,所以需要websocket通信,选择了使用channels
模块,主要记录下channels
部署的配置和一些坑.
原项目是通过nginx+uwsgi部署的,这里我没做任何改动,只是通过nginx将特定请求路径代理到daphne上.部署前对django
配置的一些修改可以直接参考,这个比较简单,也没有什么问题.
supervisor + daphne
第一种:
这是我最初在网上查到配置,很多文章基本是类似的:
[program:asgi] directory=/your/path/project-name # 项目主路径 command=daphne -b localhost -p 8001 --proxy-headers project-name.asgi:application # 启动命令 autostart=true autorestart=true stdout_logfile=/tmp/asgi.log redirect_stderr=true
需要注意一点,如果项目运行在虚拟环境,supervisor安装在主环境中,那么daphne
需要用绝对路径.
这种配置是可用的,但有个问题是只能单进程运行,如果打开多个进程(添加numprocs=n
)会报端口占用的错误.
第二种
然后就是,文档中提供的配置是多进程的,但有一个小问题,先贴出我的配置:
[fcgi-program:asgi] socket=tcp://localhost:8001 directory=/my/app/path # 区别在这里 command=daphne --fd 0 --access-log - --proxy-headers mysite.asgi:application ########### numprocs=4 process_name=asgi%(process_num)d autostart=true autorestart=true stdout_logfile=/your/log/asgi.log redirect_stderr=true
注意:fcgi-program是做了一层代理的,现在一个网络请求的传递就是:nginx -> supervisor -> daphne -> backend-app.
所以这里daphne绑定的unix-socket或者文件描述符都是用来与supervisor通信的,这就与上面第一种配置不同了
我去掉了-u xxx/xxx.sock
的配置项,因为这一项是没有必要的.在命令行中看一下daphne
的帮助,里面有这样两条:--fd file_descriptor
选项会绑定到一个文件描述符,并替换掉对host/port和unix-socket的绑定.
注意: 根据,fcgi-program中部署的程序只能通过文件描述符0与supervisor进行通信.所以这里如果只用unix-socket其实是无效的.
nginx
nginx的配置基本参考channels的文档:
upstream channels-backend { server localhost:8001; } ... server { ... location /ws/ { proxy_pass http://channels-backend; 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; } ... }
(我其实没有搞懂文档里提到的try_files的用法-_-!)
我遇到的一个小问题,起初我在supervisor配置里用了
127.0.0.1
,然后在nginx里用了localhost
,发现居然连不通,这才第一次意识到他两个是有区别的.
因为localhost
的传输不走网卡,不受网卡或防火墙的限制,所以建议本地程序间通信用localhost
.