Django3.0 異步功能嚐鮮

上週Django官方正式發佈了Django 3.0版本,其中最重要的更新莫過於對ASGI的支持。今天對Django 3.0的異步功能作了簡單的試用,分析下過程,但願對你們有幫助。html

具體的詳細更新列表可參考官方 Django 3.0 release notes, 這裏再也不贅述,下面咱們開始。python

準備工做

在開始以前咱們先來準備下環境,直接使用 Pycharm 新建一個項目,並新建虛擬環境.git

獲得以下項目:github

相比以前版本的 django 項目,多了一個asgi.py。這即是ASGI的服務的入口文件了,內容基本同wsgi.pyweb

ASGI 協議知識

在使用ASGI 特性以前,先讓咱們瞭解下,什麼是 ASGI?django

ASGIWSGI,都是一種 Web 服務網關接口協議,是在CGI的標準上構建的。瀏覽器

CGI(通用網關接口, Common Gateway Interface),簡單來講就是解析瀏覽器等客戶端發送給服務端的請求,並組裝須要返回的 HTTP 請求的一種通用協議,處理這個過程的程序,咱們就能夠叫 CGI 腳本。互聯網早起的動態網頁都是基於CGI標準的。緩存

(圖片來源: juejin.im/post/5de689…

WSGI,是一種 Python 專用的 Web 服務器網關接口,它分爲兩部分"服務器(或網關)"和"應用程序(或應用框架)"。「服務器」,通常獨立於應用框架,爲應用程序運行提供環境信息和一個回調函數(Callback Function)。當應用程序完成處理請求後,透過回調函數,將結果回傳給服務器。經常使用的WSGI服務器有: uwsgigunicon。「應用程序」,是各類實現了WSGI標準的 Python web 框架了,經常使用的有DjangoFlask等。bash

ASGI(Asynchronous Server Gateway Interface)是 Django 團隊提出的一種具備異步功能的 Python web 服務器網關接口協議。可以處理多種通用的協議類型,包括 HTTP,HTTP2 和 WebSocket。WSGI是基於 HTTP 協議模式的,不支持WebSocket,而ASGI的誕生則是爲了解決 Python 經常使用的 WSGI 不支持當前 Web 開發中的一些新的協議標準(WebSocket、Http2 等)。同時,ASGI向下兼容WSGI標準,能夠經過一些方法跑WSGI的應用程序。經常使用的「服務器」有DaphneUvicorn服務器

更多ASGI資料可參考文檔

使用過程

瞭解了ASGI,咱們進入正題。關於ASGIDjango release Notes文檔中並無過多的介紹,只有一個部署的文檔 How to deploy with ASGI

看了下,主要說了兩種部署方式:daphne 和 uvicorn。其中"必須使用 DaphneUvicorn部署,纔會是 ASGI 服務,直接 runnerserver 是同步服務"這句給了咱們提醒,想要使用 ASGI,便不能直接 runerserver。

咱們隨便選一種使用方式,並啓動服務:

# 安裝
pip install  uvicorn

# 啓動服務
uvicorn django3_demo.asgi:application
複製代碼

啓動日誌以下:

$ uvicorn django3_demo.asgi:application
INFO:     Started server process [48508]
INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO:     Waiting for application startup.
INFO:     ASGI 'lifespan' protocol appears unsupported.
INFO:     Application startup complete.
複製代碼

根據ASGI的特性,能夠支持 HTTP、HTTP2 和 WebSocket。那咱們來進行下 websocket 和 http 的測試。

websocket 測試

打開瀏覽器 console 控制檯,新建一個 websocket 連接,出現以下錯誤:

看服務錯誤以下:

INFO:     Application startup complete.
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/Users/xiumin1/.local/share/virtualenvs/django3_demo/lib/python3.6/site-packages/uvicorn/protocols/websockets/websockets_impl.py", line 153, in run_asgi
    result = await self.app(self.scope, self.asgi_receive, self.asgi_send)
  File "/Users/xiumin1/.local/share/virtualenvs/django3_demo/lib/python3.6/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__
    return await self.app(scope, receive, send)
  File "/Users/xiumin1/.local/share/virtualenvs/django3_demo/lib/python3.6/site-packages/django/core/handlers/asgi.py", line 146, in __call__
    % scope['type']
ValueError: Django can only handle ASGI/HTTP connections, not websocket.

複製代碼

Django can only handle ASGI/HTTP connections, not websocket ,貌似 Django 的 ASGI 尚未徹底實現,僅支持 HTTP。

http 測試

在瀏覽器輸入http://127.0.0.1:8000 出現了咱們熟悉的小火箭頁面。這只是簡單的啓動頁面,咱們須要寫個異步的 view 和 model 來具體操做下。

翻閱了一遍文檔,在一個小角落裏:

令我失望的找到了以下說明:

Django has developing support for asynchronous (「async」) Python, but does not yet support asynchronous views or middleware; they will be coming in a future release.

主要意思是現階段不支持異步的 view 和中間件。那也就說明無法使用 Django 原生的方式來實現ASGI了。

到此,異步功能的試用告一段落。結論,現階段Django原生仍是沒法徹底的支持ASGI的服務。若是想徹底實現ASGI服務,仍是須要 Channelsstarlette

通過翻閱資料,我找到了 Django 原生異步主要推進者Andrew Godwin的一篇博客, 描述了異步功能開發的時間軸。大體以下:

  • Django 2.1:當前進行中的版本。沒有異步工做。
  • Django 2.2:添加異步 ORM 和查看功能的初始工做,但默認狀況下全部內容默認都同步,而且異步支持主要基於線程池。
  • Django 3.0:將內部請求處理堆棧重寫爲徹底異步的,添加異步中間件,表單,緩存,會話,身份驗證。對全部變爲僅異步的 API 開始棄用過程。
  • Django 3.1:繼續改善異步支持,潛在的異步模板更改
  • Django 3.2:完成不推薦使用的過程,並擁有一個異步的 Django。

從如今 3.0 發佈的功能看,實現貌似與該時間抽差了一個版本,只實現了應該到 2.2 的功能。

到這裏今天的分享就結束了。最後,仍是但願 Django 的異步功能早點來臨,到時候咱們便能直接使用 django 開發各類異步特性的功能,而沒必要安裝三方軟件。

擴展閱讀

相關文章
相關標籤/搜索