FastAPI使用async?乱用async导致灾难,不如直接不用
警告:亂用async導(dǎo)致災(zāi)難
背景
研發(fā)過程中,測試同事反饋,調(diào)用XX接口的時候其他的接口全部沒法調(diào)用了,都被阻塞住了。
我當(dāng)時認(rèn)為,機(jī)器太挫了,有其他任務(wù)在機(jī)器上運行,請求無法處理。但,很快我就被打臉。
這里用一個DEMO來展示,只包含了三個文件
第一個文件 ?fastApiServer,這個文件里面定義了兩個API,并啟動了服務(wù)器
import xmlrpc.client import uvicorn from datetime import datetime from fastapi import FastAPIapp = FastAPI()@app.get("/root1") async def root1():print("1111", datetime.now())# 調(diào)用RPCurl = 'http://{}:{}'.format("127.0.0.1", 1081)client = xmlrpc.client.ServerProxy(url)res = client.test1()if res is not None:print(res)# 調(diào)用RPC結(jié)束print("2222", datetime.now())return {"message": "Hello World"}@app.get("/root2") async def root2():print("3333", datetime.now())# 調(diào)用RPCurl = 'http://{}:{}'.format("127.0.0.1", 1081)client = xmlrpc.client.ServerProxy(url)res = client.test2()if res is not None:print(res)# 調(diào)用RPC結(jié)束print("4444", datetime.now())return {"message": "Hello World"}uvicorn.run(app=app, host="0.0.0.0", port=1080, timeout_keep_alive=1200)第二個文件rpcServer.py
import time from socketserver import ThreadingMixIn from xmlrpc.server import SimpleXMLRPCServerclass ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer):name = "xml-server"def test1():print("test1()")time.sleep(10)status = "1"return statusdef test2():print("test2()")status = "2"return statusserver = ThreadXMLRPCServer(('0.0.0.0', 1081)) server.register_function(test1, "test1") server.register_function(test2, "test2") server.serve_forever()第三個文件 test.py 測試文件,先后發(fā)送兩個請求
import time from threading import Threadimport requestsdef k1():requests.get(url="http://127.0.0.1:1080/root1")def k2():requests.get(url="http://127.0.0.1:1080/root2")Thread(target=k1).start() time.sleep(1) Thread(target=k2).start()啟動服務(wù)
跑測試
?
我震驚發(fā)現(xiàn),兩個先后間隔1秒到達(dá)的請求,竟然需要等待第一個請求結(jié)束之后,才會去處理第二個請求
問題原因
如果你定義了async函數(shù),函數(shù)體卻是同步的調(diào)用,將導(dǎo)致函數(shù)執(zhí)行過程變成串行。
解決方案
方法一 直接刪除async
import xmlrpc.client import uvicorn from datetime import datetime from fastapi import FastAPIapp = FastAPI()@app.get("/root1") def root1():print("1111", datetime.now())# 調(diào)用RPCurl = 'http://{}:{}'.format("127.0.0.1", 1081)client = xmlrpc.client.ServerProxy(url)res = client.test1()if res is not None:print(res)# 調(diào)用RPC結(jié)束print("2222", datetime.now())return {"message": "Hello World"}@app.get("/root2") def root2():print("3333", datetime.now())# 調(diào)用RPCurl = 'http://{}:{}'.format("127.0.0.1", 1081)client = xmlrpc.client.ServerProxy(url)res = client.test2()if res is not None:print(res)# 調(diào)用RPC結(jié)束print("4444", datetime.now())return {"message": "Hello World"}uvicorn.run(app=app, host="0.0.0.0", port=1080, timeout_keep_alive=1200)修改后,再次運行測試腳本
結(jié)果和預(yù)期一致。
結(jié)論
在不了解所調(diào)用函數(shù)是否支持await的情況下,不使用async,使用普通函數(shù)即可
參考鏈接
https://blog.csdn.net/qq_29518275/article/details/109360617
https://fastapi.tiangolo.com/async/
總結(jié)
以上是生活随笔為你收集整理的FastAPI使用async?乱用async导致灾难,不如直接不用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Leetcode987 二叉树的垂序遍历
- 下一篇: Leetcode周赛5193. 删除字符