項目中需要一個聊天室的功能,所以需要websocket通信,選擇了使用 模塊,主要記錄下 部署的配置和一些坑. 原項目是通過nginx+uwsgi部署的,這裡我沒做任何改動,只是通過Nginx將特定請求路徑代理到daphne上.部署前對 配置的一些修改可以直接參考 "官方文檔" ,這個比較簡單,也沒 ...
項目中需要一個聊天室的功能,所以需要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的綁定.
註意: 根據supervisor:fcgi-program的文檔,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
.