FastAPI 엔드포인트에서 HTTPX를 사용한 비동기 호출
FastAPI에서 ThreadPoolExecutor 사용에 대한 우려
귀하 사용으로 인한 영향에 대한 우려를 표명했습니다. 특히 스레드 생성, 호스트 부족 및 애플리케이션 충돌과 관련된 FastAPI 엔드포인트의 동시.futures.ThreadPoolExecutor. 과도한 스레드 생성은 리소스에 부담을 주고 잠재적으로 성능 문제를 일으킬 수 있으므로 이러한 우려는 타당합니다.
권장 사항: HTTPX Async 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와 함께 HPX의 스트리밍 응답을 활용해 보세요.
... # (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')
위 내용은 FastAPI 엔드포인트에서 동시 HTTP 호출을 수행할 때 리소스 부담과 잠재적인 충돌을 방지하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!