淺談FastAPI到底用不用async問題
FastAPI到底用不用async
FastAPI的很快,歸功于它的異步處理。
那我們用FastAPI框架時,函數(shù)到底用不用async模式?
官方文檔:
https://fastapi.tiangolo.com/async/
做個實驗
from fastapi import APIRouter import time import asyncio router = APIRouter() @router.get("/a") async def a(): time.sleep(1) return {"message": "異步模式,但是同步執(zhí)行sleep函數(shù),執(zhí)行過程是串行的"} @router.get("/b") async def b(): loop = asyncio.get_event_loop() await loop.run_in_executor(None, time.sleep, 1) return {"message": "線程池中運行sleep函數(shù)"} @router.get("/c") async def c(): await asyncio.sleep(1) return {"message": "異步模式,且異步執(zhí)行sleep函數(shù)"} @router.get("/d") def d(): time.sleep(1) return {"message": "同步模式,但是FastAPI會放在線程池中運行,所以很快"}
我們并發(fā)100個請求分別測試這4個接口。
結(jié)果
- /a接口:100秒
- /b接口:1秒
- /c接口:1秒
- /d接口:3秒
/a接口
- fastapi框架會將async函數(shù)會放到event loop中運行。
- 雖然使用了async,但是函數(shù)內(nèi)部并沒有用到await,所以堵塞了。
- 執(zhí)行過程是串行的,所以總耗時100秒。
/b接口
- 利用asyncio異步IO獲取當(dāng)前的event loop。
- 然后將time.sleep(1)放到一個event loop中去運行,函數(shù)內(nèi)部用到了await,所以無堵塞。
- 執(zhí)行過程是并行的,所以總耗時1秒。
/c接口
- 使用異步IO的sleep取代了普通的同步sleep。
- 原理與/b接口一致。
- 執(zhí)行過程是并行的,所以總耗時1秒。
/d接口
- 這個函數(shù)沒有async修飾,即一個普通函數(shù)。
- 但是FastAPI會將函數(shù)放到thread pool中執(zhí)行。
- 服務(wù)器是8核CPU,線程池的默認(rèn)配置是核心數(shù)*5=40。
- 服務(wù)器在第一秒和第二秒分別處理40個請求,第三秒處理20個請求。
- 所以100個并發(fā)總耗時3秒。
總結(jié)
官方說,無論你是否使用async,F(xiàn)astAPI都會采用異步的方式處理。
但是,如果你定義了async函數(shù),函數(shù)體卻是同步的調(diào)用(例:/a接口),將導(dǎo)致函數(shù)執(zhí)行過程變成串行。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
python中not、and和or的優(yōu)先級與詳細(xì)用法介紹
這篇文章主要給大家介紹了python中not、and和or的優(yōu)先級與詳細(xì)用法介紹,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11Python super( )函數(shù)用法總結(jié)
今天給大家?guī)淼闹R是關(guān)于Python的相關(guān)知識,文章圍繞著super( )函數(shù)展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06pycharm進行Git關(guān)聯(lián)和取消方式
這篇文章主要介紹了pycharm進行Git關(guān)聯(lián)和取消方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06