django+channels+dephne實現websockrt部署


當你的django項目中使用channels增加了websocket功能的時候,在使用runserver命令啟動時,既可以訪問http請求,又可以訪問websocket請求。但是當你使用uWSGI+nginx的來啟動項目的時候,你會發現http請求可用,但是websocket請求永遠是404的錯誤。這是為什么呢?

因為在我們的標准生產環境部署中,使用的事WSGI協議來啟動的我們的項目,也就是使用的wsgi.py這個文件來對接的uWSGI服務器。但是我們channels使用的ASGI協議,在我們使用uWSGI來啟動項目的時候,關於ASGI的一些配置他就找不到了。這就導致了你所有的websocket請求都是404。在查閱了大量的資料和閱讀了官方文檔以后終於解決了這個問題。

這個問題的解決有兩種方案:

  • 啟用uWSGI來處理所有的http請求,另外開啟一個daphne服務來處理websocket請求。這樣的好處是按照請求類型分流,兩種請求方式互不干擾。

  • 另外一種則是啟用daphne服務來處理http和websocket這兩種請求。在daphne服務內部他會根據請求類型的不同分開處理。讓你既可以訪問websocket又可以訪問http。

安裝Daphne

pip install daphne

在setting.py同級的目錄下新建一個asgi.py文件

"""
ASGI entrypoint. Configures Django and then runs the application
defined in the ASGI_APPLICATION setting.
"""

import os
import django
from channels.routing import get_default_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
django.setup()
application = get_default_application()

使用Daphne來啟動項目

daphne -b 0.0.0.0 -p 8000 myproject.asgi:application

這種方式只是在后台啟動了你的項目,我們為了保證項目的穩定性,保證項目在意外死亡以后可以迅速的重啟,我們來使用supervisor來管理我們的daphne服務。

 

什么是supervisor

  1. Supervisor是用Python開發的一個client/server服務,是Linux/Unix系統下的一個進程管理工具,不支持Windows系統。

  1. 作用:它可以很方便的監聽、啟動、停止、重啟一個或多個進程。

  1. 用Supervisor管理的進程,當一個進程意外被殺死,supervisort監聽到進程死后,會自動將它重新拉起

  1. 很方便的做到進程自動恢復的功能,不再需要自己寫shell腳本來控制。

  1. 說白了,它真正有用的功能是倆個將非daemon(守護進程)程序變成deamon方式運行對程序進行監控,當程序退出時,可以自動拉起程序。

  1. 但是它無法控制本身就是daemon的服務。

安裝supervisor

yum install epel-release

yum install supervisor

不要使用pip下載supervisor,因為系統有python2.7和python3.6兩個版本,有時候會因為版本問題倒是supervisor啟動錯誤。而且pip的supervisor的安裝和使用方式也更為繁瑣一些。

在/etc/supervisord.d/文件夾下面配置被管理的服務的配置,然后啟動supervisor即可管理該服務。

下面使用supervisor來管理我們dephne服務

[program:asgi]
directory=/code/shiyanloupro/
command=daphne -b 0.0.0.0 -p 8000 --proxy-headers shiyanloupro.asgi:application
autostart=true
autorestart=true
stdout_logfile=/tmp/websocket.log  #日志
redirect_stderr=true
/etc/supervisord.d/test.ini

supervisor的管理命令

[root@linux-node1 tmp]# supervisord -c /etc/supervisord.conf  # 啟動supervisor
[root@linux-node1 tmp]# systemctl enable supervisord    # 開機自啟動
[root@linux-node1 tmp]# systemctl start supervisord     # 啟動supervisord服務
[root@linux-node1 tmp]# supervisorctl reread                    # 重新讀取多有的配置文件
[root@linux-node1 tmp]# supervisorctl update            # 配置文件修改后使用該命令加載新的配置,常和reread連用
[root@linux-node1 tmp]# supervisorctl reload            # 重新啟動配置中的所有程序

[root@linux-node1 tmp]# supervisorctl status            # 查看supervisor管理的所有進程狀態
[root@linux-node1 supervisord.d]# supervisorctl restart test            # 啟動test程序
[root@linux-node1 supervisord.d]# supervisorctl stop all                # 停止所有程序
[root@linux-node1 supervisord.d]# supervisorctl stop es       # 停止名稱es程序(如果停止所有換成all)
[root@linux-node1 tmp]# supervisorctl start es      # 啟動項目名稱es程序

接下來就是配置nginx將請求轉發到daphne服務器

upstream channels-backend {
    server localhost:8000;
}
...
server {
    ...
    location / {
        try_files $uri @proxy_to_app;
    }
    ...
    location @proxy_to_app {
        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;
    }
    ...
}
/etc/nginx/nginx.d/daphne.conf

最后來開啟你的nginx服務和dephne服務即可。

systemctl restart nginx   #重啟nginx
supervisorctl reread            #重新讀取supervisor的配置
supervisorctl update            #更新supervisor的配置
supervisorctl start asgi    #啟動asgi服務,也就是我們的daphne服務

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM