FastAPI エンドポイントでの HTTPX による非同期呼び出し
FastAPI での ThreadPoolExecutor の使用に関する懸念
あなたFastAPI エンドポイントで concurrent.futures.ThreadPoolExecutor を使用することの影響、特にスレッドの作成、ホストの枯渇、アプリケーションのクラッシュに関する懸念を表明しました。過度のスレッド作成はリソースに負担をかけ、パフォーマンスの問題を引き起こす可能性があるため、これらの懸念は正当です。
推奨事項: HTTPX 非同期 API
これらの潜在的な落とし穴を回避するには、次のことをお勧めします。 concurrent.futures.ThreadPoolExecutor の代わりに HTTPX ライブラリの非同期機能を利用します。 HTTPX は、明示的なスレッド管理を必要とせずに HTTP リクエストを作成できる効率的な非同期 API を提供します。このアプローチには、いくつかの利点があります。
作業例
次のコードスニペットは、FastAPI エンドポイントで HTTPX を使用して非同期 HTTP リクエストを実装する方法を示しています:
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
代替: RAM の使用を回避するためのストリーミング応答
応答本文全体を読み取る場合RAM への書き込みが懸念される場合は、FastAPI の 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')とともに HTTPX のストリーミング レスポンスを利用することを検討してください。
以上がFastAPI エンドポイントで同時 HTTP 呼び出しを行うときに、リソースの負担とクラッシュの可能性を回避するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。