码农行者 码农行者
首页
  • Python

    • 语言特性
    • Django相关
    • Tornado
    • Celery
  • Golang

    • golang学习笔记
    • 对比python学习go
    • 模块学习
  • JavaScript

    • Javascript
  • 数据结构预算法笔记
  • ATS
  • Mongodb
  • Git
云原生
运维
垃圾佬的快乐
  • 数据库
  • 机器学习
  • 杂谈
  • 面试
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

DeanWu

软件工程师
首页
  • Python

    • 语言特性
    • Django相关
    • Tornado
    • Celery
  • Golang

    • golang学习笔记
    • 对比python学习go
    • 模块学习
  • JavaScript

    • Javascript
  • 数据结构预算法笔记
  • ATS
  • Mongodb
  • Git
云原生
运维
垃圾佬的快乐
  • 数据库
  • 机器学习
  • 杂谈
  • 面试
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • Django 3.0 异步试用分享

    • 准备工作
      • ASGI 协议知识
        • 使用过程
          • websocket 测试
          • http 测试
        • 扩展阅读
        • 开发语言
        • Python
        • Django
        DeanWu
        2019-12-12
        目录

        Django 3.0 异步试用分享

        上周Django官方正式发布了Django 3.0版本,其中最重要的更新莫过于对ASGI的支持。今天对Django 3.0的异步功能做了简单的试用,分析下过程,希望对大家有帮助。

        具体的详细更新列表可参考官方 Django 3.0 release notes (opens new window), 这里不再赘述,下面我们开始。

        # 准备工作

        在开始之前我们先来准备下环境,直接使用 Pycharm 新建一个项目,并新建虚拟环境.

        得到如下项目:

        相比之前版本的 django 项目,多了一个asgi.py。这便是ASGI的服务的入口文件了,内容基本同wsgi.py。

        # ASGI 协议知识

        在使用ASGI 特性之前,先让我们了解下,什么是 ASGI?

        ASGI和WSGI,都是一种 Web 服务网关接口协议,是在CGI的标准上构建的。

        CGI(通用网关接口, Common Gateway Interface),简单来说就是解析浏览器等客户端发送给服务端的请求,并组装需要返回的 HTTP 请求的一种通用协议,处理这个过程的程序,我们就可以叫 CGI 脚本。互联网早起的动态网页都是基于CGI标准的。

        WSGI,是一种 Python 专用的 Web 服务器网关接口,它分为两部分"服务器(或网关)"和"应用程序(或应用框架)"。「服务器」,一般独立于应用框架,为应用程序运行提供环境信息和一个回调函数(Callback Function)。当应用程序完成处理请求后,透过回调函数,将结果回传给服务器。常用的WSGI服务器有: uwsgi、gunicon。「应用程序」,是各种实现了WSGI标准的 Python web 框架了,常用的有Django、Flask等。

        ASGI(Asynchronous Server Gateway Interface)是 Django 团队提出的一种具有异步功能的 Python web 服务器网关接口协议。能够处理多种通用的协议类型,包括 HTTP,HTTP2 和 WebSocket。WSGI是基于 HTTP 协议模式的,不支持WebSocket,而ASGI的诞生则是为了解决 Python 常用的 WSGI 不支持当前 Web 开发中的一些新的协议标准(WebSocket、Http2 等)。同时,ASGI向下兼容WSGI标准,可以通过一些方法跑WSGI的应用程序。常用的「服务器」有Daphne、Uvicorn。

        更多ASGI资料可参考文档 (opens new window)

        # 使用过程

        了解了ASGI,我们进入正题。关于ASGI在Django release Notes文档中并没有过多的介绍,只有一个部署的文档 How to deploy with ASGI (opens new window)

        看了下,主要说了两种部署方式:daphne 和 uvicorn。其中"必须使用 Daphne或Uvicorn部署,才会是 ASGI 服务,直接 runnerserver 是同步服务"这句给了我们提醒,想要使用 ASGI,便不能直接 runerserver。

        我们随便选一种使用方式,并启动服务:

        # 安装
        pip install  uvicorn
        
        # 启动服务
        uvicorn django3_demo.asgi:application
        
        1
        2
        3
        4
        5

        启动日志如下:

        $ 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.
        
        1
        2
        3
        4
        5
        6

        根据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.
        
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11

        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服务,还是需要 Channels (opens new window) 或 starlette (opens new window)。

        经过翻阅资料,我找到了 Django 原生异步主要推动者Andrew Godwin (opens new window)的一篇博客, 描述了异步功能开发的时间轴。大致如下:

        • Django 2.1:当前进行中的版本。没有异步工作。
        • Django 2.2:添加异步 ORM 和查看功能的初始工作,但默认情况下所有内容默认都同步,并且异步支持主要基于线程池。
        • Django 3.0:将内部请求处理堆栈重写为完全异步的,添加异步中间件,表单,缓存,会话,身份验证。对所有变为仅异步的 API 开始弃用过程。
        • Django 3.1:继续改善异步支持,潜在的异步模板更改
        • Django 3.2:完成不推荐使用的过程,并拥有一个异步的 Django。

        从现在 3.0 发布的功能看,实现貌似与该时间抽差了一个版本,只实现了应该到 2.2 的功能。

        到这里今天的分享就结束了。最后,还是希望 Django 的异步功能早点来临,到时候我们便能直接使用 django 开发各种异步特性的功能,而不必安装三方软件。

        # 扩展阅读

        • Daphne 文档 (opens new window)
        • DEP0009 (opens new window)
        • Django 3.0 is going async! (opens new window)
        • A Django Async Roadmap (opens new window)
        • django developers goolge groups (opens new window)
        • 刘江-Django3.0 初体验 (opens new window)
        #Django
        上次更新: 2023/03/28, 16:27:19
        最近更新
        01
        chromebox/chromebook 刷bios步骤
        03-01
        02
        redis 集群介绍
        11-28
        03
        go语法题二
        10-09
        更多文章>
        Theme by Vdoing | Copyright © 2015-2024 DeanWu | 遵循CC 4.0 BY-SA版权协议
        • 跟随系统
        • 浅色模式
        • 深色模式
        • 阅读模式