python flask tornado fastapi sanic框架性能研究

Python Web 框架性能研究

三个方面:性能上,应用场景上,框架本身特点

性能上:

性能测试工具基本介绍:测试环境: 电脑环境:win10   i5  4G独显 8G内存       ubuntu18.04 python3.6.8   ab 2.3   python2.7

ab是Apache超文本传输协议(HTTP)的性能测试工具。       主要用它来测试框架每秒处理的请求数

并发连接数:某个时刻服务器所接受的请求数目

并发用户数:简单理解就是用户数

吞吐量(率):每秒处理的请求数

服务器平均请求等待时间:        处理完成所有请求数所花费的时间 / 总请求数      

简单理解就是:处理每个请求平均花费的时间,单位是毫秒

执行原理   例如:1000并发连接数 100并发用户数指的是        模拟100用户在同一时刻连续不断的发送1000个请求给服务器

 

测试分为5组,

分别是 100并发连接数 100并发用户数

1000并发连接数 100并发用户数

10000并发连接数 100并发用户数

10000并发连接数 500并发用户数

10000并发连接数 1000并发用户数

每组数据测了5次求的平均值

 

GET请求:

# flask
@app.route("/hello")
def hello_test():
    grate = 85
    if grate > 90:
        res = "非常优秀"
    elif grate > 80:
        res = "优秀"
    elif grate > 70:
        res = "良好"
    elif grate > 60:
        res = "及格"
    else:
        res = "不及格"
    return res

# tornado
class IndexHandler(tornado.web.RequestHandler):
    def get(self,*args,**kwargs):
        grate = 85
        if grate > 90:
            res = "非常优秀"
        elif grate > 80:
            res = "优秀"
        elif grate > 70:
            res = "良好"
        elif grate > 60:
            res = "及格"
        else:
            res = "不及格"
        self.write(res)

# sanic
@app.route("/")
async def index(request):
    grate = 85
    if grate > 90:
        res = "非常优秀"
    elif grate > 80:
        res = "优秀"
    elif grate > 70:
        res = "良好"
    elif grate > 60:
        res = "及格"
    else:
        res = "不及格"
    return text(res)

# fastapi
@app.get("/")
async def root():
    grate = 85
    if grate > 90:
        res = "非常优秀"
    elif grate > 80:
        res = "优秀"
    elif grate > 70:
        res = "良好"
    elif grate > 60:
        res = "及格"
    else:
        res = "不及格"
    return res

   测试结果:

第一吞吐量测试

python flask tornado fastapi sanic框架性能研究_第1张图片

 结论:GET请求中,sanic,fastapi框架每秒处理的请求出最多,其次是tornado和flask+gevent

第二用户平均等待时间

python flask tornado fastapi sanic框架性能研究_第2张图片

 结论:当并发用户数比较小时,各各框架之间用户平均等待时间相差是不大的,当并发用户数达到较高时,sanic框架和fastapi框架明显在用户平均等待时间上远远小于其他框架,性能更好

POST请求

#flask 
@app.route("/login",methods=["POST","GET"])
def login_test():
    if request.method == "GET":
        return render_template("index.html")
    if request.method == "POST":
        username = request.form.get("username")
        password = request.form.get("password")
        if username == "test" and password == "test":
            return "

%s,login success

"%username else: return "

login failed

" # tornado class PostHandler(tornado.web.RequestHandler): def post(self,*args,**kwargs): username = self.get_argument("username") password = self.get_argument("password") if username == "test" and password == "test": self.write("

%s,login success

"%username) else: self.write("

login failed

") # sanic @app.route('/login',methods=["GET","POST"]) async def login(request): if request.method == "GET": return await response.file("./index.html") elif request.method == 'POST': username = request.form.get("username") password = request.form.get("password") if username == "test" and password == "test": return html('

login success

') else: return html('

login fail

') # fastapi @app.post("/login") async def insert(people:People): username = people.username password = people.password if username == "test" and password == "test": return {"success":True} else: return {"success":False}

第一吞吐量

python flask tornado fastapi sanic框架性能研究_第3张图片

 结论:在POST请求上,sanic框架上远远高于其他框架,其次是fastapi,tornado和flask+gevent相差不大

第二用户平均等待时间

python flask tornado fastapi sanic框架性能研究_第4张图片

结论:

       当并发用户较小时,每个框架用户平均等待时间是相差不大的,当处于高的并发用户时,sanic和fastapi性能上要明显比其他框架快,时间短

       同时我们也发现,flask+gevent模块后,用户平均等待时间从1523直接降至690直接提升了2倍左右的性能

JSON序列化

      

# flask
@app.json_test()
def json_test():
    shop = {
        "store" :{
                "book":[
                        {
                            "title":"富爸爸穷爸爸",
                            "category":"投资理财",
                            "author":"罗伯特",
                            "price":20.
                        }
                        {
                            "title":"小狗钱钱",
                            "category":"投资理财",
                            "author":"博多舍费尔",
                            "price":15,
                        }
                        {
                            "title":"硅谷热",
                            "category":"科技",
                            "author":"朱迪丝",
                            "price":60,
                        }
                        {
                            "title":"大数据时代",
                            "category":"科技",
                            "author":"肯尼斯",
                            "price":50,
                        }
                        ],
                "bicycle":{
                           "color":"red",
                            "price":35
                           }
                }
            }
    return json(shop)

# sanic 
@app.route("/json")
async def test_json(request):
    shop = {
        "store" :{
                "book":[
                        {
                            "title":"富爸爸穷爸爸",
                            "category":"投资理财",
                            "author":"罗伯特",
                            "price":20.
                        }
                        {
                            "title":"小狗钱钱",
                            "category":"投资理财",
                            "author":"博多舍费尔",
                            "price":15,
                        }
                        {
                            "title":"硅谷热",
                            "category":"科技",
                            "author":"朱迪丝",
                            "price":60,
                        }
                        {
                            "title":"大数据时代",
                            "category":"科技",
                            "author":"肯尼斯",
                            "price":50,
                        }
                        ],
                "bicycle":{
                           "color":"red",
                            "price":35
                           }
                }
            }
    return json(shop)

# fastapi
@app.get("/json")
async def josn_test():
    shop = {
        "store" :{
                "book":[
                        {
                            "title":"富爸爸穷爸爸",
                            "category":"投资理财",
                            "author":"罗伯特",
                            "price":20.
                        }
                        {
                            "title":"小狗钱钱",
                            "category":"投资理财",
                            "author":"博多舍费尔",
                            "price":15,
                        }
                        {
                            "title":"硅谷热",
                            "category":"科技",
                            "author":"朱迪丝",
                            "price":60,
                        }
                        {
                            "title":"大数据时代",
                            "category":"科技",
                            "author":"肯尼斯",
                            "price":50,
                        }
                        ],
                "bicycle":{
                           "color":"red",
                            "price":35
                           }
                }
            }
    return shop

第一吞吐量

python flask tornado fastapi sanic框架性能研究_第5张图片

处理json上,sanic框架依然是最快的,是tornado框架的2倍,每秒处理请求高达2000多

第二用户平均等待时间

python flask tornado fastapi sanic框架性能研究_第6张图片

从JSON序列化,我们可以看出,sanic在处理很高的并发用户时,要比其他框架很快用户平均等待时间更短,flask+gevent框架在用户平均等待时间上差不多

# flask
@app.route("/template")
@app.route("/template/")
def template_test(name = None):
    return render_template("index.html",name=name)

# sanic
@app.route("/html")
async def index(request):
    return await response.file("./index.html")

# fastapi
@app.get('/html')
async def html_test(request:Request):
    return templates.TemplateResponse("index.html",{"request":request})

第一吞吐量

python flask tornado fastapi sanic框架性能研究_第7张图片

在模板处理上我们发现最快的是fastapi框架达到1600是其他框架的2倍左右

第二是用户平均等待时间

python flask tornado fastapi sanic框架性能研究_第8张图片

从数据中我们发现,当处理较高的并发用户时,fastapi的性能是最好的

当处理低的并发用户时各个框架之间是相差不大的

python2环境  vs python3环境

第一吞吐量

python flask tornado fastapi sanic框架性能研究_第9张图片

 第二用户平均等待时间

python flask tornado fastapi sanic框架性能研究_第10张图片

结论:从GET请求可以看出,python2和python3环境对于flask+gevent来说没有什么差异的

post请求 吞吐量

python flask tornado fastapi sanic框架性能研究_第11张图片

用户平均等待时间

python flask tornado fastapi sanic框架性能研究_第12张图片

在处理POST请求上,两个环境也是没有什么很大影响的

JSON序列化

第一吞吐量

python flask tornado fastapi sanic框架性能研究_第13张图片

第二 用户平均等待时间

python flask tornado fastapi sanic框架性能研究_第14张图片

对于json序列化来说,两个环境也是没有多大影响的

模板渲染

第一吞吐量

python flask tornado fastapi sanic框架性能研究_第15张图片

第二 用户平均等待时间

python flask tornado fastapi sanic框架性能研究_第16张图片

在模板渲染上,python2和python3环境对于flask+gevent是没有很大影响的

测试结果

第一:从GET,POST,JOSN,模板四个方面可以看出

1. 在处理GET,POST,JSON这三方面时,sanic是最快的 fastapi稍微差一点,tornado和flask+gevent处理能力差不多 是sanic的一半左右

2.在处理模板渲染时,fastapi框架是最快的,几乎是其他框架 的1倍左右,tornado,sanic,flask+gevent处理能力差不多

3.flask框架处理能力最差,flask+gevent模块后可以提升2倍左右 的性能,和tornado框架差不多

4. python的版本不影响flask+gevent框架在性能上的差别

原理:

sanic框架:         

       基于asyncio-Python的异步编程工具箱        

       sanic把eventloop从async替换成了uvloop        

       http解析器采用的高性能的httptools fastapi框架      

      基于 Starlette(轻量级的 ASGI 框架) 和      

      Pydantic(基于Python类型提示来定义数据验证, 序列化和文档)

tornado框架:     

      主要是基于异步非阻塞模型     

      内部封装了协程模块     

      内部有对epoll的使用

应用场景

flask:  轻量级,主要是用来写接口的一个框架,实现前后端分离,提高开发效率。Flask本身相当于一个内核,其他几乎所有的功能都需要用第三方的扩展来实现。其WSGI工具箱用Werkzeug(路由模块),模板引擎则使用Jinja2,这两个也是Flask框架的核心

tornado: 是一种Web服务器软件的开源版本。Tornado和现在的主流Web服务器框架(包括大多数Python的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。得利于其非阻塞的方式和对epoll的运用   Tornado每秒可以处理数以千计的连接,因此Tornado是实时Web服务的一个理想框架

sanic:     Sanic在处理长连接时特别有用,比如 websocket如果需要支持websockets或 进行大量持久的外部API调用          新功能方面,Sanic与flask相似,比如 通过共享Blueprints的概念,微小的子 应用程序,允许开发人员在更大的应用 程序中拆分和组织其代码      另外,Sanic框架非常快。其中一个依 赖项是Uloop,据官方文档表示可以让  asyncio的效率提高了2-4倍

fastapi: 自动生成API文档:编写API接口后,你就可以使用符合标准的UI如SwaggerUI,ReDoc等来使用APi         性能快:高性能,可以和NodeJS和Go相提并论         标准化:基于并完全兼容API的开发标准:OpenAPI(以前称为Swagger)和JSON Schema

请求方式的区别:

flask:通过路由装饰器注解的methods属性来指定视图处理函数可以接收那种请求方式 @app.route("/", methods=["get", "post"..])

tornado:可以通过直接重写父类RequestHandler中的get/post/..的请求处理方法来实现不同的请求方式的区分

sanic:通过路由装饰器注解的methods属性来指定视图处理函数可以接收那种请求方式,函数名以async开始 @app.route("/", methods=["get", "post"..]) async def xxx():      return xxx

fastapi:通过装饰器.方法名接受请求 app.get('/') async def xxx():      return xxx

静态文件:

flask:默认templates/中保存网页模板;static/中    保存静态资源,不需要配置

tornado:通过tornado.web.Application中的配置选项 template_path配置网页模板文件夹位置,static_path配置静态资源文件夹位置

sanic:静态文件和目录(如图像文件)在注册到 app.static() 方法 app.static('/static', './static')

fastapi:静态文件和目录(如图像文件)在注册到 app.mount() 方法 app.mount("/static", StaticFiles(directory="static"), name="static") templates = Jinja2Templates(directory="templates")

模板语法操作上:

flask:默认使用第三方的jinja2模板语法,是在DTL语法的基础上完善的一种专门给python使用的模板语法

tornado:默认使用jinja模板语法:经过一定改造的模板语法

sanic:本身不带模板语法,需要安装模板语法

fastapi:本身不带模板语法,需要安装模板语法

项目部署上:

flask:需要同时部署和配置 http server 和 wsgi server ,如果想支持异步还要部署 worker ,复杂度高

tornado:tornado 开发的应用因为自己实现了高效 http 处理的应用只需要部署自己就可以了,相对简单

sanic:非常简单:使用内置web服务器 ASGI webserver 或 gunicorn 或者 把Sanic放在反向代理后面如nginx

fastapi:可以使用uvicorn,或者放在反向代理后面nginx,等比较方便

 

你可能感兴趣的:(python,经验分享)