为什么长时间运行的请求会冻结我的 FastAPI 服务器?

问题描述 投票:0回答:1

我正在寻求帮助来阐明异步请求在 FastAPI 中的工作原理。 我在 t2.small EC2 实例(1 vCPU / 2GiB RAM)上部署了 FastAPI+NGINX+Uvicorn 应用程序。

这是一个简单的代理服务器,返回所提供的结果 ?url=

async def proxy(request, sUrl):
    targetResponse = urllib.request.urlopen(urllib.request.Request(url=urllib.parse.unquote(sUrl)))
    return Response(
        status_code=targetResponse.status,
        content=targetResponse.read().decode('utf-8'),
        media_type=targetResponse.headers['Content-Type']
        )

@app.get("/")
async def get_proxy(url: str = "", request: Request = {}):
    return await proxy(request, url)

如果我发送请求

myfastapiserver.com/?url=example.com
并且
example.com
无响应,则所有后续请求都必须等待,直到初始请求超时。

我的问题:

  1. 为什么在尝试从第 3 方 Web 服务获取数据时第一个请求冻结了我的服务器并且该 Web 服务没有响应?
  2. 我可以让我的服务器处理多个请求,无论每个请求需要多长时间吗?
  3. 如果我有 2 个 vCPU 而不是 1 个,会有什么区别?

预先感谢您的所有帮助!

python asynchronous fastapi
1个回答
0
投票

FastAPI 在同一事件循环中执行所有异步端点(以及依赖项)。

由于您的

proxy
函数不是异步的(它使用阻塞
urllib.request.urlopen
),它会阻塞事件循环并影响应用程序的性能。

为了避免这种情况,您可以使用

urllib.request.urlopen
的异步替代方案,或者使所有使用
proxy
函数(和其他阻塞函数)的端点同步:

@app.get("/")
def get_proxy(url: str = "", request: Request = {}):
    return await proxy(request, url)

在这种情况下,FastAPI将在单独的线程中执行此端点调用,并且不会对您的应用程序的性能产生如此大的影响。

© www.soinside.com 2019 - 2024. All rights reserved.