2020年是时候更新你的技术武器库了:Asgi vs Wsgi(FastAPI vs Flask)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_167
也许这一篇的标题有那么一点不厚道,因为Asgi(Asynchronous Server Gateway Interface)毕竟是Wsgi(Web Server Gateway Interface)的扩展,而FastAPI毕竟也是站在Flask的肩膀上才有了突飞猛进的发展,大多数人听说Asgi也许是因为Django的最新版(3.0)早已宣布支持Asgi网络规范,这显然是一个振奋人心的消息,2020年,如果你在Web开发面试中不扯一点Asgi,显然就有点落后于形势了。
那么到底啥是Wsgi,什么又是Asgi,放心,不扯CGI,不扯各种抽象概念,简单粗暴理解:
Wsgi是同步通信服务规范,客户端请求一项服务,并等待服务完成,只有当它收到服务的结果时,它才会继续工作。当然了,可以定义一个超时时间,如果服务在规定的时间内没有完成,则认为调用失败,调用方继续工作。
Wsgi简单工作原理示意图:
简单实现:
#WSGI example
def application(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return b'Hello, Wsgi\n'
Asgi是异步通信服务规范。客户端发起服务呼叫,但不等待结果。调用方立即继续其工作,并不关心结果。如果调用方对结果感兴趣,有一些机制可以让其随时被回调方法返回结果。
Asgi简单工作原理示意图:
简单实现:
#Asgi example
async def application(scope, receive, send):
event = await receive()
...
await send({"type": "websocket.send", ...})
简单总结一下:Asgi是异步的,Wsgi是同步的,而基于Wsgi的Flask是同步框架,基于Asgi的FastAPI是异步框架,就这么简单,那么同步框架和异步框架的区别到底在哪儿?为什么要把Flask换成FastAPI?
不靠拍脑门儿、也不是道听途说、人云亦云。玩技术的应该用数据说话,论点永远依托论据,所以我们来简单对两款框架的性能做一个测试,首先分别安装依赖的库。
Flask:
pip install gunicorn
pip install gevent
pip install flask
FastAPI:
pip install fastapi
pip install uvicorn
我们首先干的一件事就是,看看Flask和FastAPI如何处理来自多个客户端的多个请求。特别是当代码存在效率问题时(比如数据库查询时间长这种耗时任务),这里故意使用time.sleep()来模拟耗时任务,为什么不用asyncio呢?因为众所周知的原因:time.sleep是阻塞的。
Flask:
from flask import Flask
from flask_restful import Resource, Api
from time import sleep
app = Flask(__name__)
api = Api(app)
class Root(Resource):
def get(self):
print('睡10秒')
sleep(10)
print('醒了')
return {'message': 'hello'}
api.add_resource(Root, '/')
if __name__ == "__main__":
app.run()
FastApi:
import uvicorn
from fastapi import FastAPI
from time import sleep
app = FastAPI()
@app.get('/')
async def root():
print('睡10秒')
sleep(10)
print('醒了')
return {'message': 'hello'}
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000)
分别启动服务
Flask:python3 manage.py
FastAPI:uvicorn manage:app --reload
同时一时间内,开启多个浏览器,分别并发请求首页 。
Flask:http://localhost:5000
FastAPI:http://localhost:8000
观察后台打印结果:
Flask:
FastAPI:
可以看到,同样的四次请求,Flask先是阻塞了40秒,然后依次返回结果,FastAPI则是第一次阻塞后直接返回,这代表了在FastAPI中阻塞了一个事件队列,证明FastAPI是异步框架,而在Flask中,请求可能是在新线程中运行的。将所有CPU绑定的任务移到单独的进程中,所以在FastAPI的例子中,只是在事件循环中sleep(所以异步框架这里最好不要使用time.sleep而是asyncio.sleep)。在FastAPI中,异步运行IO绑定的任务。
当然这不能说明太多问题,我们继续使用鼎鼎有名的ApacheBench分别对两款框架进行压测。
一共设置5000个请求,QPS是100(请原谅我的机器比较渣)。
ab -n 5000 -c 100 http://127.0.0.1:5000/
ab -n 5000 -c 100 http://127.0.0.1:8000/
这里为了公平起见,Flask配合Gunicorn服务器,开3个worker,FastAPI配合Uvicorn服务器,同样开3个worker。
Flask压测结果:
liuyue:mytornado liuyue$ ab -n 5000 -c 100 http://127.0.0.1:5000/
This is ApacheBench, Version 2.3 <$Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requests
Server Software: gunicorn/20.0.4
Server Hostname: 127.0.0.1
Server Port: 5000
Document Path: /
Document Length: 28 bytes
Concurrency Level: 100
Time taken for tests: 4.681 seconds
Complete requests: 5000
Failed requests: 0
Total transferred: 1060000 bytes
HTML transferred: 140000 bytes
Requests per second: 1068.04 [#/sec] (mean)
Time per request: 93.629 [ms] (mean)
Time per request: 0.936 [ms] (mean, across all concurrent requests)
Transfer rate: 221.12 [Kbytes/sec] received
FastAPI压测结果:
liuyue:mytornado liuyue$ ab -n 5000 -c 100 http://127.0.0.1:8000/
This is ApacheBench, Version 2.3 <$Revision: 1826891 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requests
Server Software: uvicorn
Server Hostname: 127.0.0.1
Server Port: 8000
Document Path: /
Document Length: 19 bytes
Concurrency Level: 100
Time taken for tests: 2.060 seconds
Complete requests: 5000
Failed requests: 0
Total transferred: 720000 bytes
HTML transferred: 95000 bytes
Requests per second: 2426.78 [#/sec] (mean)
Time per request: 41.207 [ms] (mean)
Time per request: 0.412 [ms] (mean, across all concurrent requests)
Transfer rate: 341.27 [Kbytes/sec] received
显而易见,5000个总请求,Flask花费4.681秒,每秒可以处理1068.04个请求,而FastAPI花费2.060秒,每秒可以处理2426.78个请求。
结语:曾几何时,当人们谈论Python框架的性能时,总是不自觉的嗤之以鼻 ,而现在,Python异步生态正在发生着惊天动地的变化,新的框架应运而生(Sanic、FastAPI),旧的框架正在重构(Django3.0),很多库也开始支持异步(httpx、Sqlalchemy、Mortor)。软件科技发展的历史表明,一项新技术的出现和应用,常常会给这个领域带来深刻的变革,古语有云:察势者智,顺势者赢,驭势者独步天下。所以,只有拥抱未来、拥抱新技术、顺应时代才是正确的、可持续发展的道路。
原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_167
2020年是时候更新你的技术武器库了:Asgi vs Wsgi(FastAPI vs Flask)的更多相关文章
- Salt自动化之自动更新Gitfs-爱折腾技术网
Salt自动化之自动更新Gitfs-爱折腾技术网 pygit2
- 2020 年最流行的 Java 开发技术
不知不觉间,2020 年即将于十几天之后到来,作为技术圈中你,准备好迎接最新的变化了吗?在本文中,我们将以编程界最常用的编程语言 Java 为例,分享最为主流的技术与工具. 作者 | divyesh. ...
- iOS技术框架构和更新版本的技术特性
Core OS层 Sytem 系统层包括内核环境,驱动及操作系统层unix接口.内核以mach为基础,它 负责操作系统的各个方面,包括管理系统的虚拟内存,线程,文件系统,网络以及进程间通讯.这一层包含 ...
- (持续更新) C# 面试技术点、常见SQL技术点 和 解决高并发的相关技术
这篇博客 持续更新. 方便小伙伴们学习与面试前的复习
- 拭目以待!JNPF .NET将更新.NET 6技术,同时上线 3.4.1 版本
2022年5月30日,福建引迈即将上线JNPF开发平台的.NET 6版本,在产品性能上做了深度优化,且极大的提升了工作效率,加强了对云服务的改进升级,全面提升用户的使用体验. JNPF是一个以PaaS ...
- 2020年Java程序员应该学习的10大技术
对于Java开发人员来说,最近几年的时间中,Java生态诞生了很多东西.每6个月更新一次Java版本,以及发布很多流行的框架,如Spring 5.Spring Security 5和Spring Bo ...
- 软路由OpenWrt(LEDE)2020.5.10更新 UPnP+NAS+多拨+网盘+DNS优化
近期更新:2020.05.10更新-基于OpenWrt R2020.5.9版本,源码截止2020.05.10. 交流群:QQ 1030484865 电报 t.me/t_homelede 版本说 ...
- OpenWrt(LEDE)2020.4.29更新 UPnP+NAS+多拨+网盘+DNS优化+帕斯沃 无缝集成+软件包
交流群:QQ 1030484865 电报: t_homelede 固件说明 基于Lede OpenWrt R2020.4.8版本(源码截止2020.4.29)Lienol Feed及若干自行维护 ...
- HomeLede 2020.5.27更新 UPnP+NAS+多拨+网盘+DNS优化+帕斯沃/Clash 无缝集成+软件包
交流群:QQ 1030484865 电报 t.me/t_homelede 固件说明 基于Lede OpenWrt R2020.5.20版本(源码截止2020.5.27)及若干自行维护的软件包 结合 ...
随机推荐
- FinClip 前端之 VUE 核心原理总结
小程序框架有很多,都是支持前端JavaScript语言的,也是支持 vue.js 框架的.FinClip 小程序是兼容各家平台的.所以在学习了框架使用之后的进阶就要熟悉框架的底层原理. 1.数据响应式 ...
- K8S Flannel网络插件
0.前言 参考文档:https://github.com/containernetworking/cni Pod网络插件,为了实现Pod网络而需要的插件.组件.由于Kubernetes通过开放的CNI ...
- ZJOI2020
[ZJOI2015] 地震后的幻想乡 给定一个无向图 \(G\) ,\(n\) 个点 \(m\) 条边每条边权为 \([0,1]\) 的随机实数,求这张图的最小生成树的最大边权期望. \(1\le n ...
- 基于.NetCore开发博客项目 StarBlog - (10) 图片瀑布流
系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...
- 在Visual Studio 2019中使用scanf报错C4996解决办法
错误警告信息 错误C4996 'scanf': This function or variable may be unsafe. Consider using scanf_s instead. To ...
- 一款超级好用的3Dmax模型插件 支持模型多格式批量转换
对于模型设计师来说模型格式转换是最常见的事,但是每一款建模软件所支持的格式各有不同,模型互导操作太麻烦 为了解决这个难题,老子云平台研发了一款基于3dmax软件的模型格式转换插件,支持多种模型格式想换 ...
- python+anaconda+pycharm的使用
研一开学的时候开始接触了这些,但是对于其各种功能感到十分混乱,现在通过这篇博文将其功能详细的写出来. 1.python解释器 首先要了解python解释器,我们俗称的下载python也就是下载pyth ...
- Java基础-并发篇
3.1. JAVA 并发知识库 3.2. JAVA 线程实现/创建方式 3.2.1. 继承 Thread 类 Thread 类本质上是实现了 Runnable 接口的一个实例,代表一个线程的实例. ...
- SAP 实例- 下拉框
效果图 源代码 REPORT rsdemo_dropdown_listbox . DATA init. TABLES scarr. TABLES spfli. TABLES sflight. TABL ...
- SAP 隐式增强 Enhancement point
1.进入编辑器:SE38/SE37/SE24 Edit-->Enhancement Operations-->Create Option 2.填写相关信息,点击对号. 3.点击Enhanc ...