FastAPI 端点中使用 HTTPX 的异步调用
关于在 FastAPI 中使用 ThreadPoolExecutor 的担忧
您对在 FastAPI 端点中使用并发.futures.ThreadPoolExecutor 的影响表示担忧,特别是在线程创建、主机饥饿和应用程序崩溃方面。这些担忧是合理的,因为过多的线程创建可能会导致资源紧张,并可能导致性能问题。
建议:HTTPX Async API
为了避免这些潜在的陷阱,建议利用 HTTPX 库的异步功能而不是并发.futures.ThreadPoolExecutor。 HTTPX 提供了高效的异步 API,允许您发出 HTTP 请求,而无需显式的线程管理。这种方法有几个优点:
工作示例
以下代码代码片段演示了如何在 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 是一个问题,请考虑利用 HTTPX 的 Streaming 响应以及 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')
以上是在 FastAPI 端点中进行并发 HTTP 调用时,如何避免资源紧张和潜在的崩溃?的详细内容。更多信息请关注PHP中文网其他相关文章!