Python异步编程之web框架 异步vs同步 数据库IO任务压测对比
测试基本信息
主题:比较异步框架和同步框架在数据库IO操作的性能差异
python版本:python 3.8
数据库:mysql 8.0.27 (docker部署)
压测工具:locust
web框架:同步:flask 异步:starlette
请求并发量: 模拟10个用户
服务器配置: Intel(R) i7-12700F
客户端配置:Intel(R) i7-8700 3.20GHz
flask 同步框架
python中操作数据库通常使用ORM框架完成。flask 使用的ORM框架是大名鼎鼎的sqlalchemy,该框架是所有ORM框架中生态最完善的,但是sqlalchemy对异步的支持并不算友好,目前支持原生SQL操作。
定义表结构
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine, Column, Integer, String
DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/test"
engine = create_engine(DB_URI)
Base = declarative_base(engine) # SQLORM基类
class Student(Base):
__tablename__ = 'student' # 表名
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(50))
Base.metadata.create_all() # 将模型映射到数据库中
api接口
from flask import Flask, request
from sqlalchemy.orm import sessionmaker
from model import Student, engine, Base
app = Flask(__name__)
@app.route('/users')
def list_all():
session = sessionmaker(engine)() # 构建session对象
students = session.query(Student).all()
res = [stu.name for stu in students]
session.close()
return res
@app.route("/user", methods=["POST"])
def create():
session = sessionmaker(engine)() # 构建session对象
student = Student(name='Tony') # 创建一个student对象
session.add(student) # 添加到session
session.commit() # 提交到数据库
session.close()
return {"res":"success"}
if __name__ == '__main__':
app.run(port=8090, host="0.0.0.0")
接口调用
post请求
get 请求:
压测结果
并发量:225
starlette 异步框架
starlette 异步框架配套使用的ORM框架是 tortoise-orm。tortoise-orm 是一款方便、易用、可靠的异步ORM框架,文档:https://tortoise.github.io/
安装数据库
pip install tortoise-orm
pip install aiomysql
定义表结构
from tortoise import fields, models
class Users(models.Model):
id = fields.IntField(pk=True)
username = fields.CharField(max_length=20)
def __str__(self) -> str:
return f"User {self.id}: {self.username}"
api接口
from model import Users
from starlette.applications import Starlette
from tortoise.contrib.starlette import register_tortoise
from starlette.requests import Request
from starlette.responses import JSONResponse
from uvicorn.main import run
app = Starlette()
# 查询记录
@app.route("/user", methods=["GET"])
async def list_all(_: Request):
users = await Users.all()
return JSONResponse({"users": [str(user) for user in users]})
# 创建记录
@app.route("/user", methods=["POST"])
async def create(request: Request):
body = await request.json
username = body.get("user_name")
user = await Users.create(username=username)
return JSONResponse({"ret":"success"})
# 表迁移
register_tortoise(app, db_url="mysql://root:123456@127.0.0.1:3306/test", modules={"models": ["model"]}, generate_schemas=True)
if __name__ == "__main__":
run(app, host="0.0.0.0")
接口调用
post请求创建一个用户
get请求
压测结果
并发量:1496
性能对比
并发曲线图对比:
参数对比:
框架 | 数据库IO | 延迟 | 纯框架无IO | 文件IO |
---|---|---|---|---|
fastapi | 225 | 47 ms | 463 | 453 |
starlette | 1496 | 6 ms | 1539 | 1538 |
总结
在数据库读写方面,异步框架性能是同步框架的6倍,可以看出同步框架在数据库读写频繁时性能下降明显,几乎是无IO读写的一半,而异步框架在有数据库IO的情况下并发几乎保持不变。主要原因是在当前简单的场景下数据库读操作耗时少而连接释放耗时较多,异步编程非阻塞模型不等待,所以数据库连接释放耗时并不阻塞异步框架。下一篇比较redis IO的并发性能。
连载一系列关于python异步编程的文章。包括同异步框架性能对比、异步事情驱动原理等。首发微信公众号,欢迎关注第一时间阅读。
Python异步编程之web框架 异步vs同步 数据库IO任务压测对比的更多相关文章
- python高级编程之 web静态服务器
返回固定数据 import socket def request_handler(new_client_socket): """ 响应客户端请求的核心函数 "& ...
- python异步编程之asyncio
python异步编程之asyncio 前言:python由于GIL(全局锁)的存在,不能发挥多核的优势,其性能一直饱受诟病.然而在IO密集型的网络编程里,异步处理比同步处理能提升成百上千倍的效率, ...
- 异步编程之Promise(3):拓展进阶
异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...
- 异步编程之Promise(2):探究原理
异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...
- 200行自定义异步非阻塞Web框架
Python的Web框架中Tornado以异步非阻塞而闻名.本篇将使用200行代码完成一个微型异步非阻塞Web框架:Snow. 一.源码 本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞 ...
- Tornado----自定义异步非阻塞Web框架:Snow
Python的Web框架中Tornado以异步非阻塞而闻名.本篇将使用200行代码完成一个微型异步非阻塞Web框架:Snow. 一.源码 本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞 ...
- 150行代码搭建异步非阻塞Web框架
最近看Tornado源码给了我不少启发,心血来潮决定自己试着只用python标准库来实现一个异步非阻塞web框架.花了点时间感觉还可以,一百多行的代码已经可以撑起一个极简框架了. 一.准备工作 需要的 ...
- 异步编程之Generator(1)——领略魅力
异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...
- (翻译)异步编程之Promise(1):初见魅力
原文:https://www.promisejs.org/ by Forbes Lindesay 异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2) ...
- net异步编程之await
net异步编程之await 初探asp.net异步编程之await 终于毕业了,也顺利进入一家期望的旅游互联网公司.27号入职.放肆了一个多月没写代码,好方啊. 另外一下观点均主要针对于await ...
随机推荐
- 小编亲身实操,教你配置phpstorm与xdebug的调试配置,不成功你骂我
开发php,还是找个专业的Ide较好,vscode毕竟在php上不专业,需要下载各种插件才行,还不支持多线程调试,因此小编下载了phpstorm,打算以后用phpstorm来开发php项目,断点调试代 ...
- 最新版本 Stable Diffusion 开源 AI 绘画工具之汉化篇
目录 汉化预览 下载汉化插件一 下载汉化插件二 下载汉化插件三 开启汉化 汉化预览 在上一篇文章中,我们安装好了 Stable Diffusion 开源 AI 绘画工具 但是整个页面都是英文版的,对于 ...
- 【小白晋级大师】如何设计一个支持10万人用的ChatGPT对接系统
不停地书写,方能不失在人海茫茫. 1.前言 之前给大家写了ChatGPT对接企业微信的教程,具体可看知乎链接: [奶奶看了都会]ChatGPT3.5接入企业微信,可连续对话 文章结尾说了教程只能适用于 ...
- kali装机 安装输入法 修改国内源
1-先配置国内源官方kali源 vim /etc/apt/sources.list 插入如下源 deb http://mirrors.aliyun.com/kali sana main non-fre ...
- 多态 polymorphic
多态是同一个行为具有多个不同表现形式,多态实现需要以下条件 继承父类并重写方法 父类引用指向子类对象:Animal a = new Cat(); 多态实例: //测试类 public class Te ...
- mysql迁移:mysqldump导出数据库
问题描述:要将一个mysql中六个数据库导出来,使用mysqldump导出 mysqldump使用语法:mysqldump -uroot -p -S /data/mysql/db_itax_m/mys ...
- Python 使用QQ 邮箱进行发送邮件及经验总结
今天我带大家实现下简单的发邮件功能.我们要使用到email和smtplib库,这两个库时python自带的,直接import 引用就好了,实现环境python3.6. 对QQ邮箱进行开启SMTP服务 ...
- spring boot过滤器实现项目内接口过滤
spring boot过滤器实现项目内接口过滤 业务 由于业务需求,存在两套项目,一套是路由中心,一套是业务系统. 现在存在问题是,路由中心集成了微信公众号与小程序模块功能,业务系统部署了多套服务. ...
- Flowable启动报错problem during schema upgrade&&couldn‘t upgrade db schema:
1.错误信息 problem during schema upgrade, statement alter table ACT_RU_VARIABLE add column SCOPE_ID_ var ...
- vue项目PC端如何适配不同分辨率屏幕
配置前言 项目构建:基于vue-cli3构建,使用postcss-px2rem px2rem-loader插件进行rem适配实现原理:每次打包,webpack通过使用插件postcss-px2rem, ...