Heim > Artikel > Backend-Entwicklung > Wie kann ich Ressourcenbelastungen und mögliche Abstürze vermeiden, wenn ich gleichzeitig HTTP-Aufrufe in einem FastAPI-Endpunkt durchführe?
Asynchrone Aufrufe mit HTTPX in FastAPI-Endpunkten
Bedenken hinsichtlich der Verwendung von ThreadPoolExecutor in FastAPI
Sie äußerte Bedenken hinsichtlich der Auswirkungen der Verwendung von concurrent.futures.ThreadPoolExecutor in einer FastAPI Endpunkt, insbesondere im Hinblick auf Thread-Erstellung, Host-Ausfall und Anwendungsabstürze. Diese Bedenken sind berechtigt, da eine übermäßige Thread-Erstellung die Ressourcen belasten und möglicherweise zu Leistungsproblemen führen kann.
Empfehlung: HTTPX Async API
Um diese potenziellen Fallstricke zu vermeiden, wird empfohlen, dies zu tun Nutzen Sie die asynchronen Funktionen der HTTPX-Bibliothek anstelle von concurrent.futures.ThreadPoolExecutor. HTTPX bietet eine effiziente asynchrone API, die es Ihnen ermöglicht, HTTP-Anfragen zu stellen, ohne dass eine explizite Thread-Verwaltung erforderlich ist. Dieser Ansatz bietet mehrere Vorteile:
Arbeitsbeispiel
Der folgende Codeausschnitt zeigt, wie man asynchrone HTTP-Anfragen mit implementiert HTTPX in einem FastAPI-Endpunkt:
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
Alternative: Antworten streamen, um RAM-Nutzung zu vermeiden
Wenn das Lesen der gesamten Antworttexte in den RAM ein Problem darstellt, sollten Sie die Verwendung von HTTPX in Betracht ziehen Streaming-Antworten zusammen mit FastAPIs StreamingResponse:
... # (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')
Das obige ist der detaillierte Inhalt vonWie kann ich Ressourcenbelastungen und mögliche Abstürze vermeiden, wenn ich gleichzeitig HTTP-Aufrufe in einem FastAPI-Endpunkt durchführe?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!