python的quad函数 python quart_人工智能

简评:将你的 Flask 升级到 Quart ,轻松获得 3 倍的性能提升。

自从 Flask 在 8 年前发布以来,Python 发生了很大变化,特别是引入了 asyncio之后。asyncio 允许开发像 uvloop 和 asyncpg 这样的库来大大提高性能,可惜要 Flask 集成 asyncio 或这些库并不是一件简单的事情。不过不用气馁,Quart 框架与 asyncio 可以一起使用 Flask-API。

基于共享的 Flask-API,现有的 Flask 应用程序进行很少的修改就可以变成 Quart 应用程序,然后就可以使用这些新的库来实现 Flask 无法做到的性能优化。

python的quad函数 python quart_java_02

本文详细介绍了典型的生产环境的 CRUD 应用程序从 Flask 到 Quart 的转换,并展示相关的性能改进优势。

0. 我想直接看杰伦(结论)

将这个 Flask-pyscopg2 应用程序升级到 Quart-asyncpg 应用程序可以提高 3 倍的性能,而且不需要对代码进行重大的重写或调整。

python的quad函数 python quart_python的quad函数_03

如上所示,在针对单个资源详情的请求下,Flask每秒请求为330个,而quart能达到1160个。以此类推,Quart 相比于 Flask 平均性能提高3倍。

这个比较,我使用了一个简单的只提供一个 RESTful 接口的应用程序,这是微服务架构中的常见用例。

该应用程序有三个路由。这些路由分别是:

  • 单个电影详情:GET /films/pk/
  • 所有电影:GET /films/
  • 添加新评论:POST /reviews/

源代码可以在以下网址找到:
https://github.com/pgjones/faster_than_flask_article

有两个 commit ,分别是一个 Flask 版本和一个Quart 版本。

1. 从 Flask 到 Quart

从 Flask 改用 Quart 很容易,只需要一点点改变,特别是 from flask 改为 from quart,函数变成异步函数。

def add_review():
    data = request.get_json()
    ...

变成

async def add_review():
    data = await request.get_json()
    ...

2.数据库连接,从 psycopg2 到 asyncpg

从 psycopg2 改用 asyncpg 比较麻烦,因为两者有不同的用法。

为了简化区别,我们在 Flask 应用程序中使用了 PoolWrapper,使得 psycopg2 可以使用与 asyncpg 相同的 API 进行上下文管理,即:

with pool.acquire() as connection:

这将允许通过with更改为async with来使用asyncpg。

当然,除了连接之外,Asyncpg和psycopg2还在游标使用、事务、执行参数和查询格式方面存在差异。这些差异是你在迁移过程中需要注意的。

3.部署

Flask 应用程序往往不能直接在生产环境中直接暴露给用户,这是因为Flask 本身一次只能处理一个请求。因此,常常用WSGI服务器与某种异步 worker 结合使用,例如  带 eventlet 的Gunicorn。

Quart 也可以用 Gunicorn 部署,它允许使用相同的命令来运行 Flask 和 Quart 应用程序:

$ gunicorn --config gunicorn.py 'run:create_app()'
针对 Flask 和 Quart 的性能测试是基于 Gunicorn 进行的。

4.添加测试数据

除了添加一个简单的 review 表之外,Postgresql 示例数据库还要为应用程序提供一些用于 CRUD的数据。

CREATE TABLE review (
    film_id INTEGER REFERENCES film(film_id), 
    rating INTEGER
);

5.性能测试

为了测量应用程序的性能,我们使用了wrk。它被配置为使用20个连接,以匹配数据库连接池的大小(确保最高的吞吐量,20是我使用过的典型值)。命令如下:

测试 GET 请求的命令是

$ wrk --connections 20 --duration 5m http://localhost:5000/${PATH}/

测试 POST 请求的命令是

$ wrk --connections 20 --duration 5m --script post.lua http://localhost:5000/${PATH}/

测试使用的 post.lua 文件如下:

wrk.method = "POST"
wrk.body = '{"film_id": 995, "rating": 4}'
wrk.headers["Content-Type"] = "application/json"

6.系统信息与结果

系统信息:

Postgres (9.5.10),wrk (4.0.0),Python (3.6.3),asyncpg (0.13.0),Flask (0.12.2),Gunicorn (19.7.1),psycopg2 (2.7.3.2), Quart (0.3.1)

全部运行在一台 AWS c4.large 机器上。

结果

python的quad函数 python quart_数据库_04

请注意,Quart 服务器的平均等待时间减少了 2 至 3.5 倍,每秒的请求数量增加了 2 至 3.5 倍。

7.结论

Flask 应用程序升级到 Quart 应用程序是相当简单的,因为大部分 API 是共享的,所以主要工作就是在正确的位置写asyncawait。然而,如果使用 SQLAlchemy(或其他 ORM),则从psycopg2 到 asyncpg 的改变会比较复杂,并且可能会很麻烦。

这个 demo 应用程序的性能显着提高,这个改进主要是由于 Quart 使用了 asyncpg 和 uvloop,据估计,仅 Quart 就能提供 1.5 倍的提升。

总之,从 Flask-psycopg2 应用程序升级到 Quart-asyncpg 应用程序的比较简单,并拥有非常合理的性能改进。这可能会扩展到其他基于 asyncio 的库,意味着将 Flask 应用程序转换到 asyncio 生态系统,Quart 只需要很小的工作量。