目录
本文会通过简单的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 无阻塞测试结果
Flask | Tornado | uvloop Tornado | FastApi | Sanic | |
---|---|---|---|---|---|
每秒请求数 | 1115.92 | 2089.55 | 2149.59 | 2207.03 | 6028.67 |
测试所耗时间 | 4.481 | 2.393 | 2.326 | 2.265 | 0.829 |
2.2 阻塞2秒测试结果
Flask+Gevent | Tornado | uvloop Tornado | FastApi | Sanic | |
---|---|---|---|---|---|
每秒请求数 | 49.78 | 48.70 | 48.93 | 49.83 | 49.92 |
测试所耗时间 | 100.436 | 102.669 | 102.181 | 100.346 | 100.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)