先说几句题外话,前两天看见一个帖子,提到异步框架的,里面很多人推荐 fastapi 。我个人说来很惭愧,学习 python 的 web 框架,入门是 flask,异步是 aiohttp,一直与 django 和 fastapi 这类主流的、用的人比较多的框架无缘。
所以这次也是想学习一下 fastapi,看看相对于一直使用的原生 aiohttp 有什么区别。
根据我个人理解,异步从 python3.4 版本提出以来,现在已经不是像 3.6 版本时候那样大家都不会用,现在用异步的人应该越来越多了。目前主流不管是公司内部服务,还是生产级服务,如果上 python 的话,如果要用异步的话,应该是很多人使用 django 的 asgi,一些人使用 fastapi,几乎没有人使用 aiohttp 这样。tornado 我不太了解,因为我最初接触异步是 3.5 时代,彼时 tornado 的异步是用猴子补丁实现的,所以一直也没做接触,不知道现在是怎么样了。
使用异步框架当然第一步还是看性能,我去 fastapi 官网看了一下教学,教学写的很友好,直接就推荐了 fastapi+uvicorn 的部署方案。
官网上写了 fastapi 是最快的框架之一,我们都知道 python 异步刚出的时候有很多昙花一现的框架,比如 Vibora,japronto 这些,性能做的都非常夸张,单例可以达到十万 qps,实际上是用 py 胶水封装了一下 c 框架而已,性能高也很正常,可惜这些开发社区做了 demo 出来以后都不怎么活跃了,bug 不修,没法投入生产级。
倒是 aiohttp 这个一上来看起来就很弱的,表现也不怎么亮眼的,一直更新到现在,投入生产级也完全没问题了,说句题外话,我个人使用起来主要优势就是用的熟,想实现什么效果几乎以前都做过,很快都能找到解决方案,所以学习 fastapi 对我来说倒是要考虑学习成本问题。
=====================================================================
说回正题,关于压力测试,我在虚拟机上用 wrk 进行压测,测试结果 fastapi 其实表现并不好,想问一下各位 fastapi 用的比较熟练的大佬,是我部署错误,还是它的性能表现就是这样的。
另外想问一下切换到生产级服务的话,fastapi 这条路线目前坑度怎么样,比如 web 部署里的一些常用插件,cors,basic auth,jwt 等等,还有中间件开发,支持 ws 协议等等,目前这些坑都踩的差不多了吗?这个框架从名字来看就可以看出是为 api 设计的,如果用来一体化部署 spa 之类的,有额外的坑吗?
谢谢大家
=====================================================================
附一些压测数据
#笔记本随手测一下,虚拟机给了 8 核心,所以用 16 线程 500 并发进行测试
# fastapi + uvicorn 部署,单进程
Running 20s test @ http://127.0.0.1:8000
16 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 20.88ms 3.51ms 50.90ms 95.22%
Req/Sec 0.96k 66.29 1.21k 83.54%
95737 requests in 20.01s, 13.70MB read
Requests/sec: 4784.35
Transfer/sec: 700.83KB
# aiohttp + 自带服务部署,单进程
Running 20s test @ http://127.0.0.1:8000
16 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 12.90ms 2.94ms 58.01ms 94.81%
Req/Sec 1.57k 156.69 1.82k 80.90%
156446 requests in 20.05s, 24.32MB read
Requests/sec: 7803.19
Transfer/sec: 1.21MB
# aiohttp + gunicorn(uvloop 模式) ,单进程
Running 20s test @ http://127.0.0.1:8000
16 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 6.12ms 1.08ms 23.27ms 90.35%
Req/Sec 3.28k 216.93 5.05k 72.67%
327908 requests in 20.10s, 50.97MB read
Requests/sec: 16315.63
Transfer/sec: 2.54MB
一般来说这些框架都会自带一个 web 服务,可以用来做测试什么的,一般因为稳定性,性能等等原因,都不会用在生产环境部署。但是根据这个单线程测试,fastapi 实际上单进程只有 aiohttp 的 60%,如果用 gunicorn 部署的话(值得吐槽的是 gunicorn 似乎本身也是 python 中不算快的部署方式。。),fastapi+uvicorn 的组合只有 aiohttp+gunicorn 25%左右的性能
然后是多进程 prefork 测试,采用 8 线程部署服务。
# fastapi 8 线程
Running 20s test @ http://127.0.0.1:8000
16 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 6.53ms 1.94ms 33.58ms 79.44%
Req/Sec 3.09k 476.62 4.02k 60.60%
307858 requests in 20.07s, 28.48MB read
Requests/sec: 15341.09
Transfer/sec: 1.42MB
# fastapi 增大 echo 报文长度
Running 20s test @ http://127.0.0.1:8000
16 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 9.56ms 6.59ms 51.53ms 61.89%
Req/Sec 2.18k 1.18k 6.39k 87.10%
217184 requests in 20.05s, 24.85MB read
Requests/sec: 10834.00
Transfer/sec: 1.24MB
# aiohttp 8 线程
Running 20s test @ http://127.0.0.1:8000
16 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 2.77ms 1.34ms 16.60ms 65.92%
Req/Sec 7.30k 2.28k 19.59k 73.53%
726936 requests in 20.10s, 123.40MB read
Requests/sec: 36170.63
Transfer/sec: 6.14MB
可以看到同样地,fastapi 性能只有 aiohttp 的三成左右。另外值得吐槽的是使用长报文测试下,fastapi 的 echo 性能衰退又有点厉害啊,直接掉三成。
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.