django-channels 的佈署指南,裏面的幾個重點:
- 先安裝 redis,再用 pip 安裝 asgi_redis ,然後將 settings 裡 CHANNEL_LAYERS 的 “BACKEND” 改為 asgi_redis.RedisChannelLayer ,這樣效能會比較好些。
- 執行 worker :
python manage.py runworker
- 在 wsgi.py 的同個資料夾,新增 asgi.py ,裏面放
import os from channels.asgi import get_channel_layer os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_project.settings") channel_layer = get_channel_layer() - 執行 ASGI server :
daphne your_project.asgi:channel_layer
,daphne 是在安裝 channels 時,會跟著裝上的。使用了 daphne 以後,就可以不需要 gunicorn 了,至於 uwsgi ,因為我沒在用,所以沒有深入研究。
runworker 跟 daphne 的部份,可以使用 supervisor 或者是寫 upstart script ,讓他們自動啟動。除了這些重點以外,nginx 的設定也需要調整,設定不多,只有幾行,這可以參考這兩篇文章:
大致的設定如下:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream app_server {
server 127.0.0.1:8000 fail_timeout=0;
}
server {
include mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log combined;
sendfile on;
listen 80;
client_max_body_size 4G;
# set the correct host(s) for your site
server_name example.com;
keepalive_timeout 5;
# path for static files
location /static/ {
alias /srv/app/site/static/;
}
location /media/ {
alias /var/app/media/;
}
location / {
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}
location @proxy_to_app {
proxy_buffering off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
# For websocket
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /srv/app/site/static;
}
}
我在套用這些設定以後,websocket 仍然無法順利連上,找了好半天,才找到這篇:Websockets fail to work after upgrading to 1.0.0 · Issue #466 · django/channels ,看完才知道,channels/daphne 在升級到 1.0 以後,程式裡的 websocket consumer 必須要送出
{"accept": True}
才行。這部份可以參考 1.0 的 release note ,也可以參考新的 Getting Start。不過我在參考 Getting start 時,居然沒注意到這行,也是我太大意了。