获取 FastAPI 以并行处理请求

Posted

技术标签:

【中文标题】获取 FastAPI 以并行处理请求【英文标题】:Get FastAPI to handle requests in parallel 【发布时间】: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打开了两个浏览器标签 !!这应该更容易,但我看到了痛苦。开箱即用,文档上没有提示。 【参考方案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

以上是关于获取 FastAPI 以并行处理请求的主要内容,如果未能解决你的问题,请参考以下文章

Weblogic 9中如何实现并行处理

如何在客户端处理多个请求/API 调用并行的 JWT 刷新令牌?

发送许多并行获取请求(超过最大浏览器支持)

使用并行异步请求处理错误

如何在 Django Rest Framework 中处理并行请求?

为啥我的 WCF 服务一次只处理 3 个并行请求?