「FastAPI & SQLAlchemy 实战」系列共 10 篇,从协程基础讲到数据库接口。这是第 4 篇。
结论:WSGI 是同步接口规范,ASGI 是它的异步版本。FastAPI 基于 ASGI,生产环境用 Uvicorn 运行;同步函数会被放进线程池,异步函数直接在事件循环里跑。
一、WSGI:一次请求占一个线程
WSGI 应用是一个同步可调用对象:
def application(environ, start_response):
start_response("200 OK", [("Content-Type", "text/plain")])
return [b"Hello World"]
服务器收到请求后调用它,函数必须处理完并返回响应。处理期间,这个线程/进程不能干别的。Flask、Django 旧版本走 WSGI,常配 Gunicorn、uWSGI。
二、ASGI:请求是事件
ASGI 应用是异步可调用对象,服务器把请求封装成事件,交给事件循环:
async def application(scope, receive, send):
event = await receive()
await send({
"type": "http.response.start",
"status": 200,
"headers": [(b"content-type", b"text/plain")],
})
await send({"type": "http.response.body", "body": b"Hello"})
等待数据库或网络时,事件循环可以切去处理其他请求;还支持 WebSocket、长轮询等长连接。FastAPI、Starlette 走 ASGI,配 Uvicorn。
三、对比
| WSGI | ASGI | |
|---|---|---|
| 调用方式 | 同步函数 | 异步事件 |
| 并发模型 | 线程/进程 | 事件循环 |
| WebSocket | 不支持 | 支持 |
| 典型框架 | Flask、Django 旧版 | FastAPI、Starlette |
| 典型服务器 | Gunicorn、uWSGI | Uvicorn |
四、FastAPI 里的同步与异步
async def路由:在事件循环里执行,遇到await自动切换;def路由:FastAPI 自动放进线程池(默认约CPU 核数 × 5个线程),不会阻塞事件循环,但线程池满后请求会排队。
选择原则:I/O 操作且库支持异步,用 async def;纯计算或只有同步库,用 def,不要让同步调用卡住事件循环。
五、怎么选服务器
- Flask / Django 旧版 → WSGI 服务器(Gunicorn);
- FastAPI / Starlette → ASGI 服务器(Uvicorn);
- 需要 WebSocket、实时推送 → 必须 ASGI。
开发时 uvicorn main:app --reload 即可;生产环境去掉 --reload,用多进程/容器横向扩展。
下一篇
下一篇写第一个 FastAPI 程序:路由、自动文档,以及同步/异步函数怎么选。
上一篇:Task、gather、超时与取消 | 下一篇:第一个接口、自动文档与同步/异步函数

AI项目博客






