本文詳細(xì)介紹了典型的生產(chǎn)環(huán)境的 CRUD 應(yīng)用程序從 Flask 到 Quart 的轉(zhuǎn)換,并展示相關(guān)的性能改進(jìn)優(yōu)勢。
將這個 Flask-pyscopg2 應(yīng)用程序升級到 Quart-asyncpg 應(yīng)用程序可以提高 3 倍的性能,而且不需要對代碼進(jìn)行重大的重寫或調(diào)整。
如上所示,在針對單個資源詳情的請求下,F(xiàn)lask每秒請求為330個,而quart能達(dá)到1160個。以此類推,Quart 相比于 Flask 平均性能提高3倍。
這個比較,我使用了一個簡單的只提供一個 RESTful 接口的應(yīng)用程序,這是微服務(wù)架構(gòu)中的常見用例。
該應(yīng)用程序有三個路由。這些路由分別是:
- 單個電影詳情:GET /films/pk/
- 所有電影:GET /films/
- 添加新評論:POST /reviews/
源代碼可以在以下網(wǎng)址找到:
https://github.com/pgjones/faster_than_flask_article
有兩個 commit ,分別是一個 Flask 版本和一個Quart 版本。
1. 從 Flask 到 Quart
從 Flask 改用 Quart 很容易,只需要一點(diǎn)點(diǎn)改變,特別是 from flask 改為 from quart,函數(shù)變成異步函數(shù)。
def add_review():
data = request.get_json()
...
變成
async def add_review():
data = await request.get_json()
...
**
2.數(shù)據(jù)庫連接,從 psycopg2 到 asyncpg**
從 psycopg2 改用 asyncpg 比較麻煩,因?yàn)閮烧哂胁煌挠梅ā?/p>
為了簡化區(qū)別,我們在 Flask 應(yīng)用程序中使用了 PoolWrapper,使得 psycopg2 可以使用與 asyncpg 相同的 API 進(jìn)行上下文管理,即:
with pool.acquire() as connection:
這將允許通過with更改為async with來使用asyncpg。
當(dāng)然,除了連接之外,Asyncpg和psycopg2還在游標(biāo)使用、事務(wù)、執(zhí)行參數(shù)和查詢格式方面存在差異。這些差異是你在遷移過程中需要注意的。
3.部署
Flask 應(yīng)用程序往往不能直接在生產(chǎn)環(huán)境中直接暴露給用戶,這是因?yàn)镕lask 本身一次只能處理一個請求。因此,常常用WSGI服務(wù)器與某種異步 worker 結(jié)合使用,例如 帶 eventlet 的Gunicorn。
Quart 也可以用 Gunicorn 部署,它允許使用相同的命令來運(yùn)行 Flask 和 Quart 應(yīng)用程序:
$ gunicorn --config gunicorn.py 'run:create_app()'
針對 Flask 和 Quart 的性能測試是基于 Gunicorn 進(jìn)行的。
4.添加測試數(shù)據(jù)
除了添加一個簡單的 review 表之外,Postgresql 示例數(shù)據(jù)庫還要為應(yīng)用程序提供一些用于 CRUD的數(shù)據(jù)。
CREATE TABLE review (
film_id INTEGER REFERENCES film(film_id),
rating INTEGER
);
5.性能測試
為了測量應(yīng)用程序的性能,我們使用了wrk。它被配置為使用20個連接,以匹配數(shù)據(jù)庫連接池的大小(確保最高的吞吐量,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.系統(tǒng)信息與結(jié)果
系統(tǒng)信息:
Postgres (9.5.10),wrk (4.0.0),Python (3.6.3),asyncpg (0.13.0),F(xiàn)lask (0.12.2),Gunicorn (19.7.1),psycopg2 (2.7.3.2), Quart (0.3.1)
全部運(yùn)行在一臺 AWS c4.large 機(jī)器上。
結(jié)果
請注意,Quart 服務(wù)器的平均等待時間減少了 2 至 3.5 倍,每秒的請求數(shù)量增加了 2 至 3.5 倍。
7.結(jié)論
Flask 應(yīng)用程序升級到 Quart 應(yīng)用程序是相當(dāng)簡單的,因?yàn)榇蟛糠?API 是共享的,所以主要工作就是在正確的位置寫async
和await
。然而,如果使用 SQLAlchemy(或其他 ORM),則從psycopg2 到 asyncpg 的改變會比較復(fù)雜,并且可能會很麻煩。
這個 demo 應(yīng)用程序的性能顯著提高,這個改進(jìn)主要是由于 Quart 使用了 asyncpg 和 uvloop,據(jù)估計,僅 Quart 就能提供 1.5 倍的提升。
總之,從 Flask-psycopg2 應(yīng)用程序升級到 Quart-asyncpg 應(yīng)用程序的比較簡單,并擁有非常合理的性能改進(jìn)。這可能會擴(kuò)展到其他基于 asyncio 的庫,意味著將 Flask 應(yīng)用程序轉(zhuǎn)換到 asyncio 生態(tài)系統(tǒng),Quart 只需要很小的工作量。
-
接口
+關(guān)注
關(guān)注
33文章
8611瀏覽量
151252 -
應(yīng)用程序
+關(guān)注
關(guān)注
37文章
3271瀏覽量
57727 -
flask
+關(guān)注
關(guān)注
0文章
16瀏覽量
3623
發(fā)布評論請先 登錄
相關(guān)推薦
評論