FastAPI 使用 sleep 后无法处理并发请求

2022-04-18 23:50:18 +08:00
 Richard14

按照官网提供的代码运行 hello world 服务器

from fastapi import FastAPI
import asyncio
import uvicorn

app = FastAPI()

@app.get("/")
async def root():
    print("sleeping")
    await asyncio.sleep(5) # 
    return {"message": "Hello World"}

if __name__ == '__main__':
    uvicorn.run("server:app") 

为了模拟单个请求处理时间较长的情况用了 asyncio.sleep 。但是运行之后发现如果在浏览器里同时发出三个请求,那么后端会等到第一个请求的 sleep 结束之后才会开始处理第二个请求,以此类推。

感觉很怪,这里用的是 asyncio.sleep 而不是 time.sleep ,为啥会有这种表现呢,好像进程在调用 await asyncio.sleep()的当时就直接挂起了一样。正常不应该是单个协程 sleep 之后,事件循环还要清空其他线程的任务,全都没有任务了才会挂起等待 sleep 的回信么?

2701 次点击
所在节点    Python
6 条回复
ClericPy
2022-04-19 00:06:13 +08:00
chrome 浏览器一个 host 只创建一个连接(以前看到是 6 个)

用 curl 测吧, 快成年经问题了...
hhhhhh123
2022-04-20 11:13:01 +08:00
你理解错了吧 asyncio 他是本质是单线程, 或者说是 单线程里面的多线程 , 顶多就是 一个睡 5 秒, 一个睡 3 秒, 正常的时间是 5 + 3 , 协程响应时间就会变成 5 秒 .. 这玩意不是很熟 可以看看文档: https://docs.python.org/zh-cn/3/library/asyncio-task.html
hhhhhh123
2022-04-20 11:18:00 +08:00
一个线程中含有 N 个耗时任务, 协程可以在一个线程中将 N 个耗时同时执行, 所以称为 单线程里的多线程
zzl22100048
2022-04-20 12:34:24 +08:00
不要用浏览器测试
Richard14
2022-04-20 22:08:40 +08:00
@ClericPy 谢谢,年经水问题丢人了

@hhhhhh123 你写的东西我看了三分钟没看懂,我觉得想说的话没想好之前可以不说。。
ClericPy
2022-04-20 23:18:48 +08:00
@Richard14 不丢人, 这问题谁都遇到过, 当初让我懵逼了一星期

关键遇到这种问题完全不知道该怎么搜, 用尽了我的 lowb 英语词汇量才搜到的. 属于那种反直觉的常识, 只能靠经验完全没思路

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/847778

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX