速度快 3 倍的烧瓶应用

速度快 3 倍的烧瓶应用

原文:https://medium.com/hackernoon/3x-faster-than-flask-8e89bfbe8e4f

夸脱作为烧瓶的升级

自从大约 8 年前第一次发布 Flask 以来,Python 一直在发展,特别是随着 asyncio 的引入。Asyncio 允许开发诸如 uvloopasyncpg 之类的库,据报道(这里是,这里是这里是),以提高性能,远远超过以前可能的性能。遗憾的是,Flask 不容易与 asyncio 或这些库结合。然而,Flask-API 可以通过 Quart 框架与 asyncio 一起使用。

Quart 为 Flask 应用程序使用 asyncio 提供了最简单的过渡,因为它共享 Flask-API。这意味着现有的 Flask 应用程序可以毫不费力地发展成 Quart 应用程序,然后使用这些新的库来利用 Flask 无法实现的性能改进。

本文档详细介绍了典型生产 CRUD 应用从烧瓶到夸脱的转换,并展示了典型生产部署的性能改进。

TL;博士;医生

将这款 Flask-pyscopg2 应用升级到 Quart-asyncpg 应用,性能提升了 3 倍,而无需对代码进行重大重写或调整。总结结果,

Route           | Flask | Quart | Ratio 
                | Req/s | Req/s | (Quart/Flask)
-----------------------------------------------
GET /films/995/ |   330 |  1160 |          3.5
GET /films/     |    99 |   195 |          2.0
POST /reviews/  |   325 |  1114 |          3.4

该应用程序

为了进行比较,我将考虑一个简单的应用程序,它简单地提供了一个 RESTful 数据库接口。这是微服务架构中的一个常见用例,提供了一个非常简单的代码库进行比较。

该应用程序有两个蓝图,总共包括三条路线。这些路线旨在代表典型的 CRUD 使用,即GET /films/<int:id>/单个资源、GET /films/所有资源、POST /reviews/新资源。

源代码可以在 https://github.com/pgjones/faster_than_flask_article[获得](https://github.com/pgjones/faster_than_flask_article)注意有两个提交,一个 Flask 版本和一个 Quart 版本。

从烧瓶到夸脱的演变

从 flask 到 quart 的演变意味着很容易并且需要最小的改变,特别是从 Flask 的导入被改变为从 Quart,函数变成异步的。全的一个例子是,

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

这就变成了,

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

从 psycopg2 到 asyncpg 的演变

发展 psycopg2 代码以使用 asyncpg 要稍微复杂一些,因为两者有不同的用法。为了简化差异,Flask 应用程序中使用了一个PoolWrapper来提供一个上下文管理的 psycopg2 连接,该连接使用与 asyncpg 相同的 API,即with pool.acquire() as connection:。这允许通过将with更改为async with来使用 asyncpg。

除了连接之外,Asyncpg 和 psycopg2 在游标使用、事务、执行参数和查询格式上也有所不同。这些大多是不同的约定,细节最好在 diff 中考虑。

部署

将 Flask 应用程序直接暴露给生产流量不太可能扩展,也不能真正代表典型的生产环境。这是因为 Flask 本身一次只能处理一个请求。相反,WSGI 服务器通常与某种异步工作器结合使用,例如 Gunicorneventlet

Quart 最好与 Gunicorn 一起部署,它允许使用相同的命令来运行 Flask 和 Quart 应用程序,

$ gunicorn --config gunicorn.py 'run:create_app()'

配置文件的区别仅在于使用了哪个 worker(event let 用于 Flask,Quart-UVLoop 用于 Quart)。

性能测量是在 Gunicorn 后面运行 Flask 和 Quart 应用程序的情况下进行的。

数据库ˌ资料库

Postgresql 示例数据库用于以一种粗鲁的方式给应用程序一些东西来对抗。除了添加一个简单的回顾表之外,

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

性能测定

使用 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 文件定义这里

测试系统

数据库 Postgres (9.5.10)、wrk (4.0.0)和 apps 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 机器上。

结果

全部结果如下表所示,

Route           | Requests per second | Average Latency [ms]  |
                |   Flask  |   Quart  |   Flask   |   Quart   |
---------------------------------------------------------------
GET /films/995/ |   330.22 |  1160.27 |     60.55 |     17.23 |
GET /films/     |    99.39 |   194.58 |    201.14 |    102.76 |
POST /reviews/  |   324.49 |  1113.81 |     61.60 |     18.22 |

请注意,四分之一服务器的每秒请求数增加了 2 到 3.5 倍,平均延迟相应减少了 2 到 3.5 倍。

结论

从 Flask 应用程序到 Quart 应用程序的演变相当容易,因为共享 API 主要意味着在正确的位置编写async & await的工作。然而,如果使用 SQLAlchemy(或其他 ORM ),从 psycopg2 到 asyncpg 的演变会更加复杂,可能会更麻烦。

应用程序的性能明显提高。这一改进主要归功于 Quart 启用的 asyncpg 和 uvloop 的使用。据估计,仅 Quart 一项就能提供 1.5 倍的速度提升。

总之,从 Flask-psycopg2 应用程序到 Quart-asyncpg 应用程序的过渡是相当容易的,并且给出了非常合理的性能改进。这可能会扩展到任何其他基于 asyncio 的库,这意味着 Quart 可以让 Flask 应用程序轻松过渡到 asyncio 生态系统。


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除