在FastAPI 端點中使用ThreadPoolExecutor 的潛在陷阱
在FastAPI 端點中使用並發.futures.Thoole.系統資源的擔憂精疲力盡。以下是關鍵考慮因素:
線程增殖和資源匱乏
ThreadPoolExecutor 管理線程池。每個端點呼叫都可能創建新線程,從而導致線程過度增殖。這可能會給系統資源帶來壓力,尤其是當多個請求同時發生時。
HTTPX 的改良方法
為了減輕這些風險,建議改用 HTTPX 函式庫。 HTTPX 提供了一個非同步客戶端,無需建立新執行緒即可有效處理多個請求。
HTTPX 設定
HTTPX 用戶端可以設定為控制連接數並保持-活動連接,讓您可以根據應用程式的需求自訂行為。
FastAPI 中的非同步支援
FastAPI 本身支援使用 async 關鍵字的非同步操作。這允許您非同步執行 HTTP 請求,而不會阻塞事件循環。
非同步函數和 HTTPX
要在 FastAPI 端點中非同步使用 HTTPX,請定義一個非同步函數使用 AsyncClient 實例發出 HTTP 請求。
管理 HTTPX 用戶端
您可以使用 FastAPI 中的生命週期掛鉤來管理 HTTPX 用戶端的生命週期。這可確保客戶端在啟動時初始化並在關閉時關閉,以正確處理資源清理。
流式回應
為了避免將整個回應正文讀入內存,請考慮在 HTTPX 和 FastAPI 的 StreamingResponse 類別中使用串流回應。
範例程式碼
以下是使用 HTTPX 並最佳化執行緒管理的 FastAPI 端點的範例:
from fastapi import FastAPI, Request from contextlib import asynccontextmanager import httpx import asyncio async def lifespan(app: FastAPI): # HTTPX client settings limits = httpx.Limits(max_keepalive_connections=5, max_connections=10) timeout = httpx.Timeout(5.0, read=15.0) # Initialize the HTTPX client async with httpx.AsyncClient(limits=limits, timeout=timeout) as client: yield {'client': client} app = FastAPI(lifespan=lifespan) @asynccontextmanager async def send(client): req = client.build_request('GET', URL) yield await client.send(req, stream=True) @app.get('/') async def main(request: Request): client = request.state.client # Make HTTPX requests in a loop responses = [await send(client) for _ in range(5)] # Use a streaming response to return the first 50 chars of each response return StreamingResponse(iter_response(responses))
以上是為什麼不建議在 FastAPI 端點中使用 ThreadPoolExecutor?的詳細內容。更多資訊請關注PHP中文網其他相關文章!