【问题标题】:Get FastAPI to handle requests in parallel获取 FastAPI 以并行处理请求
【发布时间】:2021-09-17 13:54:49
【问题描述】:

这是我的琐碎fastapi应用:

from datetime import datetime
import asyncio

import uvicorn
from fastapi import FastAPI


app = FastAPI()

@app.get("/delayed")
async def get_delayed():
    started = datetime.now()
    print(f"Starting at: {started}")
    await asyncio.sleep(10)
    ended = datetime.now()
    print(f"Ending at: {ended}")
    return {"started": f"{started}", "ended": f"{ended}"}

if __name__ == "__main__":
    uvicorn.run("fastapitest.main:app", host="0.0.0.0", port=8000, reload=True, workers=2)

当我连续两次调用它时,第二个函数中的代码在第一个请求完成之前不会开始执行,产生如下输出:

Starting at: 2021-09-17 14:52:40.317915
Ending at: 2021-09-17 14:52:50.321557
INFO:     127.0.0.1:58539 - "GET /delayed HTTP/1.1" 200 OK
Starting at: 2021-09-17 14:52:50.328359
Ending at: 2021-09-17 14:53:00.333032
INFO:     127.0.0.1:58539 - "GET /delayed HTTP/1.1" 200 OK

鉴于该函数标记为 async 并且我是 awaiting sleep,我希望得到不同的输出,例如:

Starting at: ...
Starting at: ...
Ending at: ...
INFO:     127.0.0.1:58539 - "GET /delayed HTTP/1.1" 200 OK
Ending at: ...
INFO:     127.0.0.1:58539 - "GET /delayed HTTP/1.1" 200 OK

[用于通话 我刚刚在 localhost:8000/delayed 上打开了 2 个浏览器选项卡]

我错过了什么?

【问题讨论】:

  • 你是怎么打电话的?
  • @alex_noname 我刚刚在localhost:8000/delayed打开了两个浏览器标签
  • !!这应该更容易,但我看到了痛苦。开箱即用,文档上没有提示。

标签: python python-asyncio fastapi


【解决方案1】:

它按预期并行工作 - 它只是一个浏览器的事情:chrome 在检测到不同选项卡中请求的相同端点时,将等待第一个被完全解析以检查结果是否可以缓存。

如果您将来自不同进程的 3 个 http 请求放在 shell 中,则结果符合预期:

content-length: 77
content-type: application/json
date: Fri, 17 Sep 2021 19:51:39 GMT
server: uvicorn

{
    "ended": "2021-09-17 16:51:49.956629",
    "started": "2021-09-17 16:51:39.955487"
}


HTTP/1.1 200 OK
content-length: 77
content-type: application/json
date: Fri, 17 Sep 2021 19:51:39 GMT
server: uvicorn

{
    "ended": "2021-09-17 16:51:49.961173",
    "started": "2021-09-17 16:51:39.960850"
}


HTTP/1.1 200 OK
content-length: 77
content-type: application/json
date: Fri, 17 Sep 2021 19:51:39 GMT
server: uvicorn

{
    "ended": "2021-09-17 16:51:49.964156",
    "started": "2021-09-17 16:51:39.963510"
}


在每个浏览器选项卡的 URL 上添加一个随机的(即使未使用)查询参数都将取消尝试缓存的行为。

相关问题:Chrome stalls when making multiple requests to same resource?

【讨论】:

  • 我在发布后看到,如果我从不同的浏览器发出请求,它会起作用,并认为这是服务器端的东西,从标头和查询参数中进行某种散列并防止多个相同的请求同时。看来我错了。谢谢解释
  • 我有一个问题,FastAPI/uvicorn 是否为每个请求创建单独的 python 进程并并行处理它们,或者所有请求都在同一个 python 进程中处理,这意味着我们必须非常具体全局变量。请帮忙,我一直在努力寻找解决方案。
  • 这是同一个进程,同一个线程 - 否则使用异步将毫无意义。你不应该按惯例使用全局变量,但在异步项目中你不能!确保您的函数需要的所有数据都通过参数传递,或者尝试使用“contextvars”(使用起来很麻烦)-docs.python.org/3/library/contextvars.html
猜你喜欢
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
  • 2018-03-02
  • 1970-01-01
  • 1970-01-01
  • 2012-12-18
相关资源
最近更新 更多