一代版本一代神:利用Docker在Win10系统极速体验Django3.1真实异步(Async)任务
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_177

就在去年(2019年),Django官方发布3.0版本,内核升级宣布支持Asgi,这一重磅消息让无数后台研发人员欢呼雀跃,弹冠相庆。大喜过望之下,小伙伴们兴奋的开箱试用,结果却让人大跌眼镜:非但说好的内部集成Websocket没有出现,就连原生的异步通信功能也只是个壳子,内部并未实现,很明显的换汤不换药,这让不少人转身投入了FastAPI的怀抱。不过一年之后,今天8月,Django3.1版本姗姗来迟,这个新版本终于一代封神,不仅支持原生的异步视图,同时也支持异步中间件,明显整了个大活。

本次我们利用Docker制作一款基于Django3.1.1的项目镜像,实际体验一下Django原生异步的魅力。

首先在宿主机安装新版Django

pip install Django==3.1.1

新建一个项目,名字为django31

django-admin.py startproject django31 .

进入项目目录可以发现,熟悉的入口文件mange.py已经消失不见,新增了asgi.py文件用来启动项目,这里我们使用异步服务器uvicorn来启动新版Django,而uvicorn对windows系统支持不够友好,所以使用Docker来构建一个运行镜像,简单方便,进入django31目录,新建Dockerfile:

FROM python:3.7
WORKDIR /Project/django31 COPY requirements.txt ./
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple COPY . .
ENV LANG C.UTF-8
WORKDIR /Project
CMD ["uvicorn", "django31.asgi:application","--host","0.0.0.0"]

这里需要注意一点,Docker每创建一个容器,会在iptables中添加一个规则,每个容器都会在本机127.17.X.X范围内分配一个地址,容器绑定的主机端口会映射到本机的127.17.X.X的容器抛出端口上。所以容器内部的项目绑定的ip不能是127.0.0.1,要绑定为0.0.0.0,这样绑定后容器内部app的实际ip由Docker自动分配,所以这里uvicorn启动参数需要用host强制绑定为0.0.0.0。

随后在项目中创建依赖文件requirements.txt:

django==3.1.1
uvicorn
httpx

开始编译镜像文件:

docker build -t 'django31' .

编译成功后大概1g左右

liuyue:django31 liuyue$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
django31 latest e8afbbbb9305 30 minutes ago 919MB

然后我们来启动项目:

docker run -it --rm -p 8000:8000 django31

后台显示启动顺利,绑定在容器内的0.0.0.0:

liuyue:django31 liuyue$ docker run -it --rm -p 8000:8000 django31
INFO: Started server process [1]
INFO: Waiting for application startup.
INFO: ASGI 'lifespan' protocol appears unsupported.
INFO: Application startup complete.
INFO: Uvicorn running on http://0.0.0.0:8000 (Press CTRL+C to quit)

浏览器访问:http://localhost:8000

熟悉的小火箭又起飞了,接下来我们来编写第一个异步视图views.py

from django.http import HttpResponse
async def index(request):
return HttpResponse("异步视图")

修改一下路由文件urls.py

from django.contrib import admin
from django.urls import path
from django31.views import index urlpatterns = [
path('admin/', admin.site.urls),
path("", index)
]

重新编译镜像:

docker build -t 'django31' .
docker run -it --rm -p 8000:8000 django31

访问http://localhost:8000

没有问题,还记得去年我们曾经使用Siege对Django2.0版本进行压力测试吗?现在我们再来测一下

siege -c150 -t60S -v -b 127.0.0.1:8000

150个并发持续一分钟,看看新版Django的抗压能力怎么样:

liuyue:~ liuyue$ siege -c150 -t60S -v -b 127.0.0.1:8000  

{	"transactions":			       10517,
"availability": 100.00,
"elapsed_time": 59.70,
"data_transferred": 0.12,
"response_time": 0.84,
"transaction_rate": 176.16,
"throughput": 0.00,
"concurrency": 148.58,
"successful_transactions": 10517,
"failed_transactions": 0,
"longest_transaction": 1.13,
"shortest_transaction": 0.45
}
liuyue:~ liuyue$

从测试结果看,整体性能虽然没有质的提高,但是也还算是差强人意,乞丐级主机在uvicorn的加持下单机200个左右并发还是能抗住的。

接下来我们来体验一下真正的技术,Django内置的原生异步任务,分别同步和异步两种方式使用httpx来请求接口,方法中人为的阻塞10秒钟:



from django.http import HttpResponse  

import asyncio
from time import sleep
import httpx #异步请求
async def http_call_async():
for num in range(10):
await asyncio.sleep(1)
print(num)
async with httpx.AsyncClient() as client:
r = await client.get("https://v3u.cn")
print(r) #同步请求
def http_call_sync():
for num in range(10):
sleep(1)
print(num)
r = httpx.get("https://v3u.cn")
print(r)

再分别通过同步和异步视图进行调用:

async def async_view(request):
loop = asyncio.get_event_loop()
loop.create_task(http_call_async())
return HttpResponse("非阻塞视图") def sync_view(request):
http_call_sync()
return HttpResponse("阻塞视图")

修改路由:

from django.contrib import admin
from django.urls import path
from django31.views import index, async_view, sync_view urlpatterns = [
path('admin/', admin.site.urls),
path("", index),
path("async/", async_view),
path("sync/", sync_view),
]

重新编译:

docker build -t 'django31' .
docker run -it --rm -p 8000:8000 django31

访问 http://localhost:8000/sync/ 看看同步的效率

很明显过程中阻塞了10秒,然后我们才等到页面结果:

再来试试不一样的,访问http://localhost:8000/async/

16毫秒,无视阻塞,瞬间响应。

通过动图我们可以发现,后端还在执行阻塞任务,但是前段已经通过异步多路复用将请求任务结果返回至浏览器了。

虽然这已经很不错了,但是稍有遗憾的是,目前Django内置的ORM还是同步机制,也就是说当我们读写数据库的时候还是阻塞状态,此时的场景就是异步视图内塞入了同步操作,这该怎么办呢?可以使用内置的sync_to_async方法进行转化:

from asgiref.sync import sync_to_async
async def async_with_sync_view(request):
loop = asyncio.get_event_loop()
async_function = sync_to_async(http_call_sync)
loop.create_task(async_function())
return HttpResponse("(via sync_to_async)")

由此可见,Django3.1在异步层面真的开始秀操作了,这就带来另外一个问题,既然原生异步任务已经做得这么牛逼了,我们到底还有没有必要使用Celery?

其实关于Django的异步视图只是提供了类似于任务或消息队列的功能,但功能上并没有Celery强大。如果你正在使用(或者正在考虑)Django3.1,并且想做一些简单的事情(并且不关心可靠性),异步视图是一种快速、简单地完成这个任务的好方法。如果你需要执行重得多的、长期运行的后台进程,你还是要使用Celery。

简而言之,Django3.1的异步任务目前仅仅是解决Celery过重的一个简化方案而已。

结语:假如我们说,新世纪以来在Python在Web开发界有什么成就,无疑的,我们应该说,Django和Flask是两个颠扑不破的巨石重镇,没有了它们,Python的web开发史上便要黯然失光,Django作为第一web开发框架,要文档有文档,要功能有功能,腰斩对手于马下,敏捷开发利器。Django3.1的发布仿佛把我们又拉回到了Django一统江湖的年代,那个美好的时代,让无数人午夜梦回。

原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_177

一代版本一代神:利用Docker在Win10系统极速体验Django3.1真实异步(Async)任务的更多相关文章

  1. Docker在手,天下我有,在Win10系统下利用Docker部署Gunicorn+Flask打造独立镜像

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_164 书接上回,之前一篇:Win10环境下使用Flask配合Celery异步推送实时/定时消息(Socket.io)/2020年最 ...

  2. Win10系统下基于Docker构建Appium容器连接Android模拟器Genymotion完成移动端Python自动化测试

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_196 Python自动化,大概也许或者是今年最具热度的话题之一了.七月流火,招聘市场上对于Python自动化的追捧热度仍未消减,那 ...

  3. 浩若烟海事半功倍|利用Docker容器技术构建自动化分布式web测试集群Selenium Grid

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_195 "世界上有那么多城市,城市里有那么多的酒馆,可她,却偏偏走进了我的-",这是电影<卡萨布拉卡> ...

  4. 上穷碧落下凡尘:Win10系统下基于Docker配置Elasticsearch7配合Python3进行全文检索交互

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_166 基于文档式的全文检索引擎大家都不陌生,之前一篇文章:使用Redisearch实现的全文检索功能服务,曾经使用Rediseac ...

  5. [转]利用Docker构建开发环境

    利用Docker构建开发环境 Posted by  makewonder on 2014 年 4 月 2 日   最近接触PAAS相关的知识,在研发过程中开始使用Docker搭建了自己完整的开发环境, ...

  6. ubuntu14.04环境下利用docker搭建solrCloud集群

    在Ubuntu14.04操作系统的宿主机中,安装docker17.06.3,将宿主机的操作系统制作成docker基础镜像,之后使用自制的基础镜像在docker中启动3个容器,分配固定IP,再在3个容器 ...

  7. 利用Docker设置Node.js

      docker是一个开源的应用容器引擎,可以为我们提供安全.可移植.可重复的自动化部署的方式.docker采用虚拟化的技术来虚拟化出应用程序的运行环境.如上图一样.docker就像一艘轮船.而轮船上 ...

  8. Docker学习总结(8)——利用Docker开启持续交付之路

    持续交付即Continuous Delivery,简称CD,随着DevOps的流行正越来越被传统企业所重视.持续交付讲求以短周期.小细粒度,自动化的方式频繁的交付软件,在这个过 程中要求开发.测试.用 ...

  9. CentOS下利用Docker部署Surging

    原文:CentOS下利用Docker部署Surging 1. 安装Centos, 配置固定ip配置文件地址vi /etc/sysconfig/network-scripts/ifcfg-ens33`` ...

随机推荐

  1. 【动态UAC权限】无盾程序(win32&cmd)

    可以看到两种不同的提权方式,注意是动态,用代码提权,而不是用清单文件提前处理. 函数都写好了,这里不多做解释. win32程序: 首先需要这俩头文件,第二个我忘了啥函数要用了,总之出问题加上就对了:( ...

  2. 每日一题20180330-Linux

    一.问题 1.1 统计/var/log/下所有文件个数 1.2 查找出/var/log目录下面修改时间是7天以前,大小在50k到2M之间,并以.log结尾的文件把这些文件复制到/data目录中 1.3 ...

  3. 基于Proxmox平台搭建3D云教室

    背景 本文介绍了在 Proxmox VE 虚拟化平台上使用NVIDIA A16 GPU,开启vGPU特性,利用DoraCloud 搭建3D云教室的方案. Proxmox virtualization ...

  4. 牛客多校赛2K Keyboard Free

    Description 给定 \(3\) 个同心圆,半径分别为 \(r1,r2,r3\) ,三个点分别随机分布在三个圆上,求这个三角形期望下的面积. Solution 首先可以固定 \(A\) 点,枚 ...

  5. 是时候为Spring Boot 3.0做准备了

    2018年2月28日Spring Boot进入2.0时代,距今已经超过4年了. 2022 年 11 月 Spring Boot 3.0 将正式发布,它将基于 Spring Framework 6.0, ...

  6. 【Azure 应用服务】NodeJS Express + MSAL 实现API应用Token认证(AAD OAuth2 idToken)的认证实验 -- passport.authenticate('oauth-bearer', {session: false})

    问题描述 在前两篇博文中,对NodeJS Express应用 使用MSAL + AAD实现用户登录并获取用户信息,获取Authorization信息 ( ID Token, Access Token) ...

  7. 论文解读(GraphMAE)《GraphMAE: Self-Supervised Masked Graph Autoencoders》

    论文信息 论文标题:GraphMAE: Self-Supervised Masked Graph Autoencoders论文作者:Zhenyu Hou, Xiao Liu, Yukuo Cen, Y ...

  8. C++ 之多态总结

    前言 最近为了完成数据库系统的实验,又复习起了<C++ Primer>,上一次看这本巨著也是大二下的六月份,那时看面向对象程序编程这一章还云里雾里的,没有领会多态的奥妙,学完 Java 之 ...

  9. 【Redis】Redis Cluster初始化及PING消息的发送

    Cluster消息类型定义 #define CLUSTERMSG_TYPE_PING 0 /* Ping消息类型,节点间进行通信交换信息的消息 */ #define CLUSTERMSG_TYPE_P ...

  10. 一款超级好用的3Dmax模型插件 支持模型多格式批量转换

    对于模型设计师来说模型格式转换是最常见的事,但是每一款建模软件所支持的格式各有不同,模型互导操作太麻烦 为了解决这个难题,老子云平台研发了一款基于3dmax软件的模型格式转换插件,支持多种模型格式想换 ...