跳到主要内容

WSGI 与 ASGI

问题

WSGI 和 ASGI 是什么?它们之间有什么区别?

答案

WSGI(Web Server Gateway Interface)和 ASGI(Asynchronous Server Gateway Interface)是 Python Web 应用与服务器之间的标准接口协议。

WSGI(PEP 3333)

同步协议,一个请求占用一个线程:

# 最简 WSGI 应用
def application(environ: dict, start_response):
"""
environ: 请求环境变量(路径、方法、请求头等)
start_response: 回调函数,设置状态码和响应头
"""
status = "200 OK"
headers = [("Content-Type", "text/plain")]
start_response(status, headers)
return [b"Hello, World!"]

WSGI 服务器:Gunicorn、uWSGI、Waitress

# Gunicorn 部署 Flask/Django
gunicorn app:application -w 4 -b 0.0.0.0:8000

ASGI

异步协议,原生支持 WebSocket 和 HTTP/2:

# 最简 ASGI 应用
async def application(scope: dict, receive, send):
"""
scope: 连接信息(类型、路径、请求头等)
receive: 接收消息的协程
send: 发送消息的协程
"""
if scope["type"] == "http":
await send({
"type": "http.response.start",
"status": 200,
"headers": [(b"content-type", b"text/plain")],
})
await send({
"type": "http.response.body",
"body": b"Hello, Async World!",
})

ASGI 服务器:Uvicorn、Hypercorn、Daphne

# Uvicorn 部署 FastAPI
uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4

核心区别

特性WSGIASGI
并发模型同步(1 请求 = 1 线程)异步(事件循环)
WebSocket不支持原生支持
HTTP/2不支持支持
框架Django, FlaskFastAPI, Starlette, Django 3.0+
服务器Gunicorn, uWSGIUvicorn, Hypercorn
性能I/O 密集型较差I/O 密集型优秀

常见面试问题

Q1: Django 能用 ASGI 吗?

答案

Django 3.0+ 支持 ASGI,但 ORM 仍然是同步的。需要用 sync_to_async 包装 ORM 操作:

from asgiref.sync import sync_to_async

@sync_to_async
def get_user(user_id):
return User.objects.get(id=user_id)

# 在 async view 中使用
async def user_view(request, user_id):
user = await get_user(user_id)
return JsonResponse({"name": user.name})

Q2: Gunicorn 和 Uvicorn 怎么配合?

答案

生产环境常用 Gunicorn + Uvicorn Worker 的组合:

# Gunicorn 管理进程,Uvicorn 处理异步请求
gunicorn app:app -k uvicorn.workers.UvicornWorker -w 4

Gunicorn 负责进程管理(worker 重启、信号处理),Uvicorn Worker 负责异步 I/O。

Q3: WSGI 中间件和 ASGI 中间件有什么区别?

答案

WSGI 中间件是同步函数包装器,ASGI 中间件是异步的:

# WSGI 中间件
class WSGIMiddleware:
def __init__(self, app):
self.app = app
def __call__(self, environ, start_response):
# 前处理
return self.app(environ, start_response)

# ASGI 中间件
class ASGIMiddleware:
def __init__(self, app):
self.app = app
async def __call__(self, scope, receive, send):
# 前处理
await self.app(scope, receive, send)

相关链接