Python異步編程之web框架異步vs同步 無IO任務壓測對比

前言

在python編程中,通過協程實現的異步編程號稱能夠提高IO密集型任務的併發量。本系列比較web服務器同步框架和異步框架的性能差異,包括無IO接口和常見IO操作,如文件、mysql、redis等。使用壓測工具locust測試相同條件下兩種編程模式能夠處理請求的速度。

測試基本信息

主題:單純比較異步框架和同步框架的性能,無任何IO
python版本:python 3.8
壓測工具:locust
web框架:同步:flask 異步:aiohttp、starlette
請求併發量: 模擬10個用戶
服務器配置: Intel(R) i7-12700F
客戶端配置:Intel(R) i7-8700 3.20GHz

flask 同步框架

flask是python中輕量級web框架,特點是靈活、輕量級、擴展性高。flask同時是一個同步框架,flask誕生的時候python的異步編程體系還不成熟,當然截止到目前flask肯定是支持異步框架的。但是讓其作爲同步框架的代表,參加pk。

from flask import Flask, request

app = Flask(__name__)


@app.route('/index')
def index():
    return "hello world"


if __name__ == '__main__':
    app.run(port=5000, host="0.0.0.0")

壓測準備

locust是一個python語言開發的壓力測試工具,有圖形化界面,基於協程併發,能夠支持在單臺機器中支持數以千計的模擬用戶,也支持分佈式壓測。
使用locust壓測,併發模擬10個用戶,10個用戶儘可能快的發送請求,併發量RPS取決於請求返回的速度,也就是服務端的處理速度。

from locust import HttpUser, task

class UserBehavior(HttpUser):
    # 請求host的/index接口
    @task(1)
    def stress_index(self):
        self.client.get("/index")

locust -f locust_stress.py

訪問 127.0.0.1:8098,啓動服務,按照10個模擬用戶發送請求
image.png

壓測結果

併發量:463
image.png

aiohttp 異步框架

aiohttp 是一個基於 asyncio 的異步 HTTP 網絡模塊,它既提供了服務端,又提供了客戶端。所以可以將aiohttp用於web框架的服務端,監聽http請求。

from aiohttp import web


routes = web.RouteTableDef()

@routes.get("/index")
async def index(request):
    return web.Response(text="Hello World")


if __name__ == '__main__':
    app = web.Application()
    app.add_routes(routes)
    web.run_app(app)

壓測結果

併發量:1455
image.png

starlette 異步框架

starlette 是當下火熱的異步框架fastapi依賴的唯二模塊之一,主要用於異步請求的處理。

from starlette.applications import Starlette
from starlette.responses import JSONResponse
from starlette.routing import Route
from uvicorn.main import run


async def index(request):
    return JSONResponse({'hello': 'world'})

app = Starlette(debug=True, routes=[Route('/index', index),])

if __name__ == "__main__":
    run(app, host="0.0.0.0")

壓測結果

併發量:1539
image.png

對比

併發曲線圖對比:
image.png

參數對比:

框架 併發量 延遲
flask 463 19 ms
aiohttp 1455 6 ms
starlette 1539 5 ms

總結

可以看出異步框架的性能是同步框架的3倍多還不止,數據如此誇張的原因是同步框架的處理所有請求都是按照順序執行的,當請求有阻塞時需要等待。而異步框架處理請求遇到阻塞可以轉而處理別的請求,所以相同時間異步框架能夠處理的請求數遠高於同步。
瞭解了純框架的併發能力之後,下一篇來看看接口中有IO任務的併發對比。

準備連載一系列關於python異步編程的文章。包括同異步框架性能對比、異步事情驅動原理等。首發微信公衆號,歡迎關注第一時間閱讀。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章