Python Web框架性能对比

   

目录

1. 测试代码

        1.1 无阻塞的代码如下

        1.2 阻塞sleep 2s代码

2. ab压测结果

        2.1 无阻塞测试结果

        2.2 阻塞2秒测试结果

   3. ab的测试报告详细

        3.1 无阻塞时报告

        3.2 阻塞时报告


    本文会通过简单的demo测试Python的“Flask/FastApi/Tornado/Sanic”四种Web框架

    使用的工具是ab(Apache Bench)压测

    测试会分成两轮,一轮是无阻塞直接返回,另一轮是通过sleep 2s模拟阻塞的情况下,测试各个框架的rps

1. 测试代码

        1.1 无阻塞的代码如下

# Flask
from flask import Flask

 
app = Flask(__name__)
 
@app.route('/test')   #匹配路由
def hello():
    return "Hello World"
 
if __name__ == '__main__':
    app.run(port=7779, threaded=True)

# Tornado
import tornado.ioloop
import tornado.web
import json
import asyncio


class MainHandler(tornado.web.RequestHandler):
    async def get(self):
        self.write("Hello, world")
 
    async def post(self):
        self.write(json.dumps({"code": "0000", "msg": "Hello, world"}))
 
def make_app():
    return tornado.web.Application([
        (r"/test", MainHandler),
    ])
 
if __name__ == "__main__":
    app = make_app()
    app.listen(8001)
    tornado.ioloop.IOLoop.current().start()

# uvloop Tornado
import asyncio
 
import tornado.ioloop
import tornado.web
import json
 
import uvloop
from tornado.platform.asyncio import AsyncIOMainLoop
 
 
class MainHandler(tornado.web.RequestHandler):
    async def get(self):
        self.write("Hello, world")
 
    async def post(self):
        self.write(json.dumps({"code": "0000", "msg": "Hello, world"}))
 
def make_app():
    return tornado.web.Application([
        (r"/test", MainHandler),
    ])
 
 
if __name__ == '__main__':
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    AsyncIOMainLoop().install()
    app = make_app()
    app.listen(8002)
    asyncio.get_event_loop().run_forever()

# FastApi
from typing import Optional
 
from fastapi import FastAPI
 
app = FastAPI()
 
 
@app.get("/test")
def read_root():
    return "Hello, world"
 
 
@app.post("/test")
def read_item():
    return {"code": "0000", "msg": "Hello, world"}

# Sanic
from sanic import Sanic
from sanic.response import json,html
 
app = Sanic(name="myName")
 
@app.route('/test',methods=['GET'])
async def hello(request):
    return html("Hello, world")
 
@app.route('/test', methods=['POST'])
async def hello2(request):
    return json({"code": "0000", "msg": "Hello, world"})
 
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8003)

        1.2 阻塞sleep 2s代码

# Flask
import time
from flask import Flask
from gevent import monkey
monkey.patch_all()  # 打上猴子补丁
 
app = Flask(__name__)
 
@app.route('/test')   #匹配路由
def hello():
	time.sleep(2)
    return "Hello World"
 
if __name__ == '__main__':
    app.run(port=7779, threaded=True)

# Tornado
import tornado.ioloop
import tornado.web
import json
import asyncio


class MainHandler(tornado.web.RequestHandler):
    async def get(self):
        await asyncio.sleep(2)
        self.write("Hello, world")
 
    async def post(self):
        self.write(json.dumps({"code": "0000", "msg": "Hello, world"}))
 
def make_app():
    return tornado.web.Application([
        (r"/test", MainHandler),
    ])
 
if __name__ == "__main__":
    app = make_app()
    app.listen(8001)
    tornado.ioloop.IOLoop.current().start()

# uvloop Tornado
import asyncio
import tornado.ioloop
import tornado.web
import json
 
import uvloop
from tornado.platform.asyncio import AsyncIOMainLoop
 
 
class MainHandler(tornado.web.RequestHandler):
    async def get(self):
	    await asyncio.sleep(2)
        self.write("Hello, world")
 
    async def post(self):
        self.write(json.dumps({"code": "0000", "msg": "Hello, world"}))
 
def make_app():
    return tornado.web.Application([
        (r"/test", MainHandler),
    ])
 
 
if __name__ == '__main__':
    asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
    AsyncIOMainLoop().install()
    app = make_app()
    app.listen(8002)
    asyncio.get_event_loop().run_forever()

# FastApi
import asyncio
from typing import Optional
from fastapi import FastAPI
 
app = FastAPI()
 
 
@app.get("/test")
async def read_root():
    await asyncio.sleep(2)
    return "Hello, world"
 
 
@app.post("/test")
def read_item():
    return {"code": "0000", "msg": "Hello, world"}

# Sanic
import asyncio
from sanic import Sanic
from sanic.response import json,html
 
app = Sanic(name="myName")
 
@app.route('/test',methods=['GET'])
async def hello(request):
    await asyncio.sleep(2)
    return html("Hello, world")
 
@app.route('/test', methods=['POST'])
async def hello2(request):
    return json({"code": "0000", "msg": "Hello, world"})
 
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8003)

2. ab压测结果

        统一使用并发100,任务总数5000进行各个接口压测,结果如下;

        其中flask引入了gevent猴子补丁,不然同步情况下根本没法玩;

        过程中我给tornado也用上gevent协程monkey,然后性能并没有提升,不清楚是不是用的方式不对。

        2.1 无阻塞测试结果

无阻塞结果
FlaskTornadouvloop TornadoFastApiSanic
每秒请求数1115.922089.552149.592207.036028.67
测试所耗时间4.4812.3932.3262.2650.829

        2.2 阻塞2秒测试结果

阻塞结果
Flask+GeventTornadouvloop TornadoFastApiSanic
每秒请求数49.7848.7048.9349.8349.92
测试所耗时间100.436102.669102.181100.346100.159

   3. ab的测试报告详细

        3.1 无阻塞时报告

# flask
Server Software:        Werkzeug/2.2.3
Server Hostname:        127.0.0.1
Server Port:            7779

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      100
Time taken for tests:   4.481 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      920000 bytes
HTML transferred:       55000 bytes
Requests per second:    1115.92 [#/sec] (mean)
Time per request:       89.612 [ms] (mean)
Time per request:       0.896 [ms] (mean, across all concurrent requests)
Transfer rate:          200.52 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:    10   89   7.5     89     101
Waiting:        6   88   7.5     88      99
Total:         13   89   7.3     89     101

Percentage of the requests served within a certain time (ms)
  50%     89
  66%     91
  75%     92
  80%     93
  90%     95
  95%     96
  98%     97
  99%     98
 100%    101 (longest request)


# tornado
Server Software:        TornadoServer/6.1
Server Hostname:        127.0.0.1
Server Port:            8001

Document Path:          /test
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   2.393 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      1025000 bytes
HTML transferred:       60000 bytes
Requests per second:    2089.55 [#/sec] (mean)
Time per request:       47.857 [ms] (mean)
Time per request:       0.479 [ms] (mean, across all concurrent requests)
Transfer rate:          418.32 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:    27   48   2.5     47      54
Waiting:       27   48   2.5     47      54
Total:         30   48   2.3     47      54

Percentage of the requests served within a certain time (ms)
  50%     47
  66%     48
  75%     48
  80%     48
  90%     48
  95%     53
  98%     54
  99%     54
 100%     54 (longest request)
 
# uvloop tornado
Server Software:        TornadoServer/6.1
Server Hostname:        127.0.0.1
Server Port:            8002

Document Path:          /test
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   2.326 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      1025000 bytes
HTML transferred:       60000 bytes
Requests per second:    2149.59 [#/sec] (mean)
Time per request:       46.520 [ms] (mean)
Time per request:       0.465 [ms] (mean, across all concurrent requests)
Transfer rate:          430.34 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.6      0       6
Processing:     6   46   4.2     46      61
Waiting:        6   46   4.1     46      61
Total:         11   46   3.9     46      61

Percentage of the requests served within a certain time (ms)
  50%     46
  66%     46
  75%     47
  80%     47
  90%     50
  95%     53
  98%     54
  99%     57
 100%     61 (longest request)
 
 
# fastapi
Server Software:        
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /test
Document Length:        14 bytes

Concurrency Level:      100
Time taken for tests:   2.265 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      695000 bytes
HTML transferred:       70000 bytes
Requests per second:    2207.03 [#/sec] (mean)
Time per request:       45.310 [ms] (mean)
Time per request:       0.453 [ms] (mean, across all concurrent requests)
Transfer rate:          299.59 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:    26   45   6.5     48      72
Waiting:       26   40   4.8     41      66
Total:         26   45   6.6     48      74

Percentage of the requests served within a certain time (ms)
  50%     48
  66%     49
  75%     49
  80%     50
  90%     51
  95%     56
  98%     60
  99%     61
 100%     74 (longest request)
 

# sanic
Server Software:        
Server Hostname:        127.0.0.1
Server Port:            8003

Document Path:          /test
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   0.829 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      550000 bytes
HTML transferred:       60000 bytes
Requests per second:    6028.67 [#/sec] (mean)
Time per request:       16.587 [ms] (mean)
Time per request:       0.166 [ms] (mean, across all concurrent requests)
Transfer rate:          647.61 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1   0.5      1       3
Processing:    10   16   5.2     15      51
Waiting:        4   11   4.8     11      47
Total:         10   16   5.2     16      51

Percentage of the requests served within a certain time (ms)
  50%     16
  66%     16
  75%     16
  80%     17
  90%     17
  95%     19
  98%     48
  99%     50
 100%     51 (longest request)

        3.2 阻塞时报告

# flask 
Server Software:        Werkzeug/2.2.3
Server Hostname:        127.0.0.1
Server Port:            7779

Document Path:          /
Document Length:        11 bytes

Concurrency Level:      100
Time taken for tests:   100.436 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      920000 bytes
HTML transferred:       55000 bytes
Requests per second:    49.78 [#/sec] (mean)
Time per request:       2008.729 [ms] (mean)
Time per request:       20.087 [ms] (mean, across all concurrent requests)
Transfer rate:          8.95 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:  2001 2006  11.0   2002    2052
Waiting:     2001 2006  11.0   2002    2052
Total:       2001 2006  11.0   2002    2053

Percentage of the requests served within a certain time (ms)
  50%   2002
  66%   2002
  75%   2003
  80%   2003
  90%   2023
  95%   2037
  98%   2048
  99%   2049
 100%   2053 (longest request)
 
 
# tornado
Server Software:        TornadoServer/6.1
Server Hostname:        127.0.0.1
Server Port:            8001

Document Path:          /test
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   102.669 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      1025000 bytes
HTML transferred:       60000 bytes
Requests per second:    48.70 [#/sec] (mean)
Time per request:       2053.376 [ms] (mean)
Time per request:       20.534 [ms] (mean, across all concurrent requests)
Transfer rate:          9.75 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:  2031 2053   2.6   2053    2059
Waiting:     2031 2053   2.6   2053    2059
Total:       2035 2053   2.4   2053    2059

Percentage of the requests served within a certain time (ms)
  50%   2053
  66%   2054
  75%   2054
  80%   2055
  90%   2055
  95%   2058
  98%   2058
  99%   2059
 100%   2059 (longest request)
 
 
# uvloop tornado
Server Software:        TornadoServer/6.1
Server Hostname:        127.0.0.1
Server Port:            8002

Document Path:          /test
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   102.181 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      1025000 bytes
HTML transferred:       60000 bytes
Requests per second:    48.93 [#/sec] (mean)
Time per request:       2043.620 [ms] (mean)
Time per request:       20.436 [ms] (mean, across all concurrent requests)
Transfer rate:          9.80 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:  2001 2043  12.8   2048    2056
Waiting:     2001 2043  12.8   2048    2056
Total:       2001 2043  12.8   2048    2056

Percentage of the requests served within a certain time (ms)
  50%   2048
  66%   2049
  75%   2050
  80%   2050
  90%   2052
  95%   2054
  98%   2056
  99%   2056
 100%   2056 (longest request)
 
# fastapi
Server Software:        
Server Hostname:        127.0.0.1
Server Port:            8000

Document Path:          /test
Document Length:        14 bytes

Concurrency Level:      100
Time taken for tests:   100.346 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      695000 bytes
HTML transferred:       70000 bytes
Requests per second:    49.83 [#/sec] (mean)
Time per request:       2006.915 [ms] (mean)
Time per request:       20.069 [ms] (mean, across all concurrent requests)
Transfer rate:          6.76 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:  2000 2005   4.6   2004    2027
Waiting:     2000 2005   4.3   2004    2024
Total:       2000 2006   4.8   2004    2028

Percentage of the requests served within a certain time (ms)
  50%   2004
  66%   2005
  75%   2006
  80%   2006
  90%   2011
  95%   2018
  98%   2021
  99%   2025
 100%   2028 (longest request)
 
# sanic
Server Software:        
Server Hostname:        127.0.0.1
Server Port:            8003

Document Path:          /test
Document Length:        12 bytes

Concurrency Level:      100
Time taken for tests:   100.159 seconds
Complete requests:      5000
Failed requests:        0
Total transferred:      550000 bytes
HTML transferred:       60000 bytes
Requests per second:    49.92 [#/sec] (mean)
Time per request:       2003.174 [ms] (mean)
Time per request:       20.032 [ms] (mean, across all concurrent requests)
Transfer rate:          5.36 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       3
Processing:  2000 2003   2.3   2002    2014
Waiting:     2000 2002   2.0   2002    2014
Total:       2000 2003   2.6   2002    2017

Percentage of the requests served within a certain time (ms)
  50%   2002
  66%   2003
  75%   2003
  80%   2004
  90%   2005
  95%   2009
  98%   2013
  99%   2014
 100%   2017 (longest request)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,这是一个关于 Python Web 框架性能对比以及如何使用 Gunicorn 和 Gevent 提高 Python Web 框架性能的问题。下面是我的回答: Python Web 框架性能对比 Python 有很多优秀的 Web 框架,如 Django、FlaskTornado、Bottle 等等。这些框架都有自己的特点和优缺点,但是在性能方面却有所不同。下面是一些常见 Python Web 框架性能对比数据: 框架 | Requests/s -----|---------- Flask| 673.24 Django| 372.77 Bottle| 3,040.36 Tornado| 3,714.29 从上表可以看出,Tornado 和 Bottle 性能比较突出,而 Django 和 Flask性能稍逊一些。但是这些数据并不是绝对的,实际性能还需要根据具体的应用场景和实现方式进行测试和评估。 使用 Gunicorn 和 Gevent 提高 Python Web 框架性能 Gunicorn 和 Gevent 都是 Python Web 服务器,它们可以与常见Python Web 框架配合使用,提高 Web 应用的性能。 具体来说,Gunicorn 是一个使用 Python 编写的 WSGI HTTP 服务器,可以用于部署 Django、FlaskWeb 应用。Gunicorn 使用多进程的方式来提高并发处理能力,可以根据系统的 CPU 核数来设置进程数,同时还支持异步处理和负载均衡等特性。 Gevent 是一个基于协程的 Python 网络库,可以用于编写高性能的网络应用程序。Gevent 可以与 Python Web 框架配合使用,使用协程来处理请求,可以显著提高 Web 应用的并发处理能力和响应速度。 下面是一个使用 Gunicorn 和 Gevent 提高 Flask Web 应用性能的示例代码: ``` python from gevent import monkey monkey.patch_all() from flask import Flask app = Flask(__name__) @app.route('/') def hello(): return 'Hello, World!' if __name__ == '__main__': from gunicorn.app.base import BaseApplication from gunicorn.six import iteritems class StandaloneApplication(BaseApplication): def __init__(self, app, options=None): self.options = options or {} self.application = app super(StandaloneApplication, self).__init__() def load_config(self): config = dict([(key, value) for key, value in iteritems(self.options) if key in self.cfg.settings and value is not None]) for key, value in iteritems(config): self.cfg.set(key.lower(), value) def load(self): return self.application options = { 'bind': '0.0.0.0:8000', 'workers': 4, } StandaloneApplication(app, options).run() ``` 上面的代码使用了 Gunicorn 和 Gevent 来启动一个 Flask Web 应用,同时设置了 4 个 worker 进程来处理请求。这样可以显著提高 Web 应用的性能和并发处理能力。 希望这个回答对你有帮助!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一拳法师

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值