Panggilan Asynchronous dengan HTTPX dalam FastAPI Endpoints
Kebimbangan Mengenai Menggunakan ThreadPoolExecutor dalam FastAPI
Anda menyatakan kebimbangan tentang kesan penggunaan concurrent.futures.ThreadPoolExecutor dalam titik akhir FastAPI, terutamanya mengenai penciptaan benang, kebuluran hos dan ranap aplikasi. Kebimbangan ini adalah sah kerana penciptaan benang yang berlebihan boleh menjejaskan sumber dan berkemungkinan membawa kepada isu prestasi.Cadangan: HTTPX Async API
Untuk mengelakkan kemungkinan perangkap ini, disyorkan untuk gunakan keupayaan async pustaka HTTPX dan bukannya concurrent.futures.ThreadPoolExecutor. HTTPX menyediakan API tak segerak yang cekap yang membolehkan anda membuat permintaan HTTP tanpa memerlukan pengurusan benang yang jelas. Pendekatan ini menawarkan beberapa kelebihan:Contoh Berfungsi
Kod berikut coretan menunjukkan cara untuk melaksanakan permintaan HTTP tak segerak dengan HTTPX dalam titik akhir FastAPI:from fastapi import FastAPI, Request from contextlib import asynccontextmanager import httpx import asyncio URLS = ['https://www.foxnews.com/', 'https://edition.cnn.com/', 'https://www.nbcnews.com/', 'https://www.bbc.co.uk/', 'https://www.reuters.com/'] @asynccontextmanager async def lifespan(app: FastAPI): # customise settings limits = httpx.Limits(max_keepalive_connections=5, max_connections=10) timeout = httpx.Timeout(5.0, read=15.0) # 15s timeout on read. 5s timeout elsewhere. # Initialise the Client on startup and add it to the state async with httpx.AsyncClient(limits=limits, timeout=timeout) as client: yield {'client': client} # The Client closes on shutdown app = FastAPI(lifespan=lifespan) async def send(url, client): return await client.get(url) @app.get('/') async def main(request: Request): client = request.state.client tasks = [send(url, client) for url in URLS] responses = await asyncio.gather(*tasks) return [r.text[:50] for r in responses] # for demo purposes, only return the first 50 chars of each response
Alternatif: Respons Penstriman untuk Mengelakkan Penggunaan RAM
Jika membaca keseluruhan badan respons ke dalam RAM adalah kebimbangan, pertimbangkan untuk menggunakan respons Penstriman HTTPX bersama-sama dengan StreamingResponse FastAPI:... # (same as previous code snippet) async def iter_content(responses): for r in responses: async for chunk in r.aiter_text(): yield chunk[:50] # for demo purposes, return only the first 50 chars of each response and then break the loop yield '\n\n' break await r.aclose() @app.get('/') async def main(request: Request): client = request.state.client tasks = [send(url, client) for url in URLS] responses = await asyncio.gather(*tasks) return StreamingResponse(iter_content(responses), media_type='text/event-stream')
Atas ialah kandungan terperinci Bagaimanakah saya boleh mengelakkan ketegangan sumber dan kemungkinan ranap apabila membuat panggilan HTTP serentak dalam titik akhir FastAPI?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!