当前位置: 首页 > news >正文

meinheld-gunicorn-flask VS uvicorn-gunicorn-fastapi 性能对比测试

本文会使用如下两个项目:meinheld-gunicorn-flask 与 uvicorn-gunicorn-fastapi

前文有测过 Flask vs FastApi 性能对比测试,可能不够有说服力,这次使用了号称最快的wsgi或asgi服务器+gunicorn来运行flask或fastapi。

上面meinheld-gunicorn-flask和uvicorn-gunicorn-fastapi项目都是由fastapi的作者发起,致力于使用flask或fastapi开发高性能后端应用,然后用docker的方式快速部署。文末会给出测试结论。

名词解释

meinheld:高性能wsgi服务器
uvicorn:高性能asgi服务器
gunicorn:用来管理meinheld或uvicorn的运行,比如用多进程/多线程的方式运行meinheld或uvicorn,以便最大化性能来运行flask或fastapi程序。

测试环境

Ubuntu 22.04系统,CPU 16核,内存32G。

一、创建 meinheld-gunicorn-flask-test 目录,目录结构为
meinheld-gunicorn-flask-test
├── Dockerfile
├── app
│   ├── main.py
│   └── prestart.sh  # 可以不要这个文件
└── requirements.txt

Dockerfile内容:

FROM tiangolo/meinheld-gunicorn-flask:python3.9COPY ./requirements.txt /app/requirements.txtRUN pip install --no-cache-dir --upgrade -r /app/requirements.txtCOPY ./app /app

requirements.txt 内容

blinker==1.8.2
click==8.1.7
Flask==3.0.3
importlib_metadata==7.1.0
itsdangerous==2.2.0
Jinja2==3.1.4
MarkupSafe==2.1.5
Werkzeug==3.0.3
zipp==3.18.2

app/main.py 内容

from flask import Flaskapp = Flask(__name__)@app.route('/', methods=['GET'])
def root():return {"Hello": "Flask"}

构建docker镜像:

cd meinheld-gunicorn-flask-test/
docker build -t meinheld-gunicorn-flask-test:1.0.0 .

运行docker容器:

docker run -d --name meinheld-gunicorn-flask-test -p 8080:80 meinheld-gunicorn-flask-test:1.0.0
二、创建 uvicorn-gunicorn-fastapi-test 目录,目录结构为:
uvicorn-gunicorn-fastapi-test
├── Dockerfile
├── app
│   ├── main.py
│   └── prestart.sh  # 可以不要这个文件
└── requirements.txt

Dockerfile内容:

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.10COPY ./requirements.txt /app/requirements.txtRUN pip install --no-cache-dir --upgrade -r /app/requirements.txtCOPY ./app /app

requirements.txt 内容

annotated-types==0.7.0
anyio==4.3.0
certifi==2024.2.2
click==8.1.7
dnspython==2.6.1
email_validator==2.1.1
exceptiongroup==1.2.1
fastapi==0.111.0
fastapi-cli==0.0.4
h11==0.14.0
httpcore==1.0.5
httptools==0.6.1
httpx==0.27.0
idna==3.7
Jinja2==3.1.4
markdown-it-py==3.0.0
MarkupSafe==2.1.5
mdurl==0.1.2
orjson==3.10.3
pydantic==2.7.1
pydantic_core==2.18.2
Pygments==2.18.0
python-dotenv==1.0.1
python-multipart==0.0.9
PyYAML==6.0.1
rich==13.7.1
shellingham==1.5.4
sniffio==1.3.1
starlette==0.37.2
typer==0.12.3
typing_extensions==4.12.0
ujson==5.10.0
uvicorn==0.29.0
uvloop==0.19.0
watchfiles==0.21.0
websockets==12.0

app/main.py 内容

from fastapi import FastAPIapp = FastAPI()@app.get("/")
async def root():return {"Hello": "FastA"}

构建docker镜像:

cd uvicorn-gunicorn-fastapi-test/
docker build -t uvicorn-gunicorn-fastapi-test:1.0.0 .

运行docker容器:

docker run -d --name uvicorn-gunicorn-fastapi-test -p 8081:80 uvicorn-gunicorn-fastapi-test:1.0.0

性能测试

这里使用ab工具测试并发。先把最大打开文件数调大,执行命令:ulimit -n 65535

# 测试flask,并发3000,连接数10万
ab -n 100000 -c 3000 http://127.0.0.1:8080/Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requestsServer Software:        meinheld/1.0.2
Server Hostname:        127.0.0.1
Server Port:            8080Document Path:          /
Document Length:        18 bytesConcurrency Level:      3000
Time taken for tests:   7.209 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      16900000 bytes
HTML transferred:       1800000 bytes
Requests per second:    13871.03 [#/sec] (mean)
Time per request:       216.278 [ms] (mean)
Time per request:       0.072 [ms] (mean, across all concurrent requests)
Transfer rate:          2289.26 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0   99  12.5     99     148
Processing:    36  113  20.7    110     346
Waiting:        1   82  18.0     80     317
Total:        109  213  18.1    208     430Percentage of the requests served within a certain time (ms)50%    20866%    21275%    21880%    22590%    23495%    24298%    25299%    258100%    430 (longest request)

下面是fastapi:

# 测试fastapi,并发3000,连接数10万
ab -n 100000 -c 3000 http://127.0.0.1:8081/Benchmarking 127.0.0.1 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Completed 100000 requests
Finished 100000 requestsServer Software:        uvicorn
Server Hostname:        127.0.0.1
Server Port:            8081Document Path:          /
Document Length:        17 bytesConcurrency Level:      3000
Time taken for tests:   7.198 seconds
Complete requests:      100000
Failed requests:        0
Total transferred:      14200000 bytes
HTML transferred:       1700000 bytes
Requests per second:    13892.29 [#/sec] (mean)
Time per request:       215.947 [ms] (mean)
Time per request:       0.072 [ms] (mean, across all concurrent requests)
Transfer rate:          1926.47 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0   88  10.2     88     138
Processing:    44  124  25.8    121     223
Waiting:        1   94  27.8     82     200
Total:         99  213  24.7    208     324Percentage of the requests served within a certain time (ms)50%    20866%    22375%    22980%    23290%    24295%    25698%    27999%    287100%    324 (longest request)
结论:

fastapi(13892.29) 和 flask(13892.29)并发量几乎一样,看来 meinheld 的性能确实很高。甚至在 ab 参数 -n 100000 -c 1000 的情况下,多次测试后,fastapi和flask并发数各有胜负。

因此在开发简单快速的项目时,可以用 meinheld-gunicorn-flask 这套方案。而在需要更多异步编程,需要类型检查,或者docs(Swagger)文档时,可以用 uvicorn-gunicorn-fastapi 这套方案。

相关文章:

  • OTA在线旅行社系统架构:连接世界的科技纽带
  • 在Spring Boot项目中集成和使用MQTT
  • Qt 概述
  • 什么是SPI,和API有啥区别
  • RustGUI学习(iced/iced_aw)之扩展小部件(二十七):如何使用number_input部件?
  • 嵌入式0基础开始学习 ⅠC语言(2)运算符与表达式
  • 移动云以深度融合之服务,令“大”智慧贯穿云端
  • mysql IF语句,模糊检索
  • Python——二维字典
  • MybatisPlus中自定义sql
  • 【数据结构】二叉树的认识与实现
  • BGP策略实验(路径属性和选路规则)
  • C# 集合(六) —— 自定义集合Collection类
  • 音视频开发8 音视频中SDL的使用,SDL 在windows上环境搭建,SDL 使用 以及 常用 API说明,show YUV and play PCM
  • C++第十七弹---string使用(下)
  • css布局,左右固定中间自适应实现
  • Docker入门(二) - Dockerfile
  • JavaScript-Array类型
  • Java比较器对数组,集合排序
  • Java面向对象及其三大特征
  • Linux学习笔记6-使用fdisk进行磁盘管理
  • oschina
  • Quartz初级教程
  • vue 配置sass、scss全局变量
  • 干货 | 以太坊Mist负责人教你建立无服务器应用
  • 聚簇索引和非聚簇索引
  • 全栈开发——Linux
  • 数组大概知多少
  • 小程序button引导用户授权
  • 《天龙八部3D》Unity技术方案揭秘
  • 1.Ext JS 建立web开发工程
  • linux 淘宝开源监控工具tsar
  • 函数计算新功能-----支持C#函数
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​力扣解法汇总946-验证栈序列
  • # Apache SeaTunnel 究竟是什么?
  • #微信小程序:微信小程序常见的配置传旨
  • (02)Unity使用在线AI大模型(调用Python)
  • (11)MSP430F5529 定时器B
  • (19)夹钳(用于送货)
  • (55)MOS管专题--->(10)MOS管的封装
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (solr系列:一)使用tomcat部署solr服务
  • (理论篇)httpmoudle和httphandler一览
  • (四)linux文件内容查看
  • (一) storm的集群安装与配置
  • (一)UDP基本编程步骤
  • (原)记一次CentOS7 磁盘空间大小异常的解决过程
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • .bat批处理(一):@echo off
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net MVC中使用angularJs刷新页面数据列表
  • .Net 基于MiniExcel的导入功能接口示例
  • .NET 事件模型教程(二)
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表