fastapi框架異步執(zhí)行踩坑記錄
fastapi框架異步執(zhí)行踩坑
問題與背景
在公司項目中,使用了python作為中間件實現的主語言,項目是中間件性質的需要并行的為第三方提供服務,但是在使用過程中,出現了并行的問題,多個耗時操作,在串行,導致項目的分析操作耗時巨大。
web技術采用的是fastapi,這個技術官網介紹是并行的,用java起多線程訪問接口,得到的結論竟然是串行的,這地方就特意研究了一下。
最佳實踐
這篇文章,給我答疑解惑了:http://m.fzitv.net/python/323052zd6.htm
我在項目中,翻了一個使用的錯誤,類似的方式如下:
@router.get("/a")
async def a():
time.sleep(1)
return {"message": "異步模式,但是同步執(zhí)行sleep函數,執(zhí)行過程是串行的"}這種寫法在于接口訪問是異步的,但是執(zhí)行的時候卻是在主線程中,用同步的方法,就導致了串行了。
所以async和await應該是成對出現的,否則就不是絕對的異步:
import asyncio
@router.get("/b")
async def b():
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(None, time.sleep, 1)
return {"message": "線程池中運行sleep函數"}這種方案接口可以異步調用,并且接口中的內容也會被異步執(zhí)行,在實際使用中,可以對方法中的內容進行封裝,然后通過loop.run_in_executor去異步調用封裝的一個方法,最終實現絕對的異步。
fastapi的異步大騙/局
有部分入坑fastapi的同志們,可能經常會遇到一個耗時的密集型IO任務阻塞主線程的情況,導致接口單個接口占用整體的線程時間過長,從而影響到其他的接口響應。
很多人可能會說,fastapi不是一個異步的框架嗎?為什么會存在阻塞這個問題?
這是一個很好的問題,我之前也想過這個問題,但是后面才發(fā)現,原來是fastapi框架的接口,本身不會自動幫忙處理長耗時的任務,如生成式的請求,調用復雜的第三方api,這個過程大概需要10-20s。
假如說自己使用的http請求是直接requests庫的請求,那么就會導致阻塞。
正確的做法應該是:
使用一個異步執(zhí)行的請求方式,例如aiohttp庫,手動為請求添加上這個異步的請求方法,我就是使用這個庫解決了長耗時任務阻塞線程的問題。
首先得安裝好這個庫:
pip install aiohttp
然后就再代碼當中
from fastapi import FastAPI
import aiohttp
import asyncio
app = FastAPI()
async def long_running_task(url: str):
async with aiohttp.ClientSession() as session:
async with session.post(url, json={"load": "data"}) as response:
# 處理響應數據
data = await response.json()
return data
@app.post("/start_task/")
async def start_task():
url = "http://example.com/api" # 目標 API 的 URL
task_result = await long_running_task(url)
return task_result這樣,這個長任務就不會阻塞主線程了。
總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
用Pelican搭建一個極簡靜態(tài)博客系統(tǒng)過程解析
這篇文章主要介紹了用Pelican搭建一個極簡靜態(tài)博客系統(tǒng)過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2019-08-08
解決Atom安裝Hydrogen無法運行python3的問題
今天小編就為大家分享一篇解決Atom安裝Hydrogen無法運行python3的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08

