单Worker下Uvicorn/FastAPI同步端点的并发处理机制疑问
理解Uvicorn的异步行为
我尝试搞懂Uvicorn的运行逻辑,写了一个核心逻辑是5秒休眠的FastAPI示例应用:
import time from datetime import datetime from fastapi import FastAPI app = FastAPI() counter = 0 @app.get("/") def root(): global counter counter = counter + 1 my_id = counter print(f'I ({my_id}) am feeling sleepy') time.sleep(5) print(f'I ({my_id}) am done sleeping') return {}
我用Apache Bench执行以下命令测试这个应用:
ab -n 5 -c 5 http://127.0.0.1:8000/
得到的输出结果如下:
I (1) am feeling sleepy -- 0s I (1) am done sleeping -- 5s I (2) am feeling sleepy -- 5s I (3) am feeling sleepy -- 5s I (4) am feeling sleepy -- 5s I (5) am feeling sleepy -- 5s I (2) am done sleeping -- 10s I (4) am done sleeping -- 10s I (3) am done sleeping -- 10s I (5) am done sleeping -- 10s
我通过uvicorn main:app --workers 1命令启动应用,因为路径操作函数用的是普通def而非async def,原本以为所有请求会完全同步执行,但实际请求却并发跑起来了。
根据FastAPI文档说明:
当使用普通def而非async def声明路径操作函数时,它会在外部线程池中运行,随后被await,而非直接调用(否则会阻塞服务器)。
我现在的疑问是:这个线程池到底在哪里?用time.sleep的时候,我本来以为唯一的Worker进程会被完全阻塞才对。
内容的提问来源于stack exchange,提问作者poiuytrez
相关产品推荐
相关产品推荐

