25 分钟
实战专项

WSGI 与 ASGI 协议深度

理解 Python Web 的底层协议和服务器模型

  • 理解 WSGI 协议和同步模型
  • 理解 ASGI 协议和异步模型
  • 理解 Worker 模型和部署架构
  • 掌握 Nginx 反向代理配置

WSGI 与 ASGI 协议深度

Python Web 框架 Django/Flask/FastAPI,全都是跑在 WSGI 或 ASGI 协议上的。搞懂这个协议,才能明白部署和性能的事儿。

WSGI:同步网关协议

示例代码(可运行)

ASGI:异步网关协议

示例代码(可运行)

Worker 模型与部署

Python
# 部署架构
#
# 浏览器 → Nginx (反向代理/静态文件/负载均衡)
#            ├── gunicorn -w 4 -k uvicorn.workers.UvicornWorker
#            │     ├── Worker 1 (异步事件循环)
#            │     ├── Worker 2 (异步事件循环)
#            │     ├── Worker 3 (异步事件循环)
#            │     └── Worker 4 (异步事件循环)
#            └── 静态文件 / 媒体文件

# gunicorn 配置要点:
# -w/--workers: worker 数量,推荐 CPU核数*2+1
# -k/--worker-class: uvicorn.workers.UvicornWorker (ASGI)
# --timeout 30: 请求超时
# --max-requests 1000: 处理1000请求后重启(防内存泄漏)
# --preload: 在fork前加载应用(节省内存,但要小心fork安全)

# uvicorn 直接运行(开发/小规模):
# uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4

# 为什么需要 Nginx?
# 1. 处理静态文件(远快于 Python 动态渲染)
# 2. SSL/TLS 终止
# 3. 负载均衡(多台应用服务器)
# 4. 限流、缓存、压缩
# 5. 缓冲慢客户端(防止慢客户端拖垮worker)

print("生产架构: Nginx + gunicorn/uvicorn + 多worker")
🐍资深工程师经验谈

Worker 数量不是越多越好。CPU 密集型:CPU核数+1;I/O 密集型(LLM API调用):可以更多,注意数据库连接池大小。用 --max-requests 定期重启 worker 是防御内存泄漏的简单有效手段。慢客户端攻击(SLOWLORIS)就是故意慢慢发请求占住 worker,Nginx 的 proxy_buffering 能解决这个问题。

Nginx 反向代理配置

示例代码(可运行)
中间件

ASGI 中间件链

ASGI 中间件是一个包装应用的应用:

Python
# ASGI 中间件模式
class LoggingMiddleware:
    def __init__(self, app):
        self.app = app  # 被包装的应用

    async def __call__(self, scope, receive, send):
        if scope["type"] == "http":
            start = time.time()
            await self.app(scope, receive, send)  # 调用下游
            duration = time.time() - start
            print(f"{scope['method']} {scope['path']} {duration:.3f}s")
        else:
            await self.app(scope, receive, send)

# 中间件链:请求从外到内,响应从内到外
# 类似洋葱模型
# LoggingMiddleware → AuthMiddleware → CORSMiddleware → App
选择题

ASGI 相比 WSGI 的核心优势是?

选择题

gunicorn worker 数量推荐为?

资深工程师加餐

底层原理 · 大厂视角 · 工程经验,点卡片展开

模型并不直接认识字符或单词,它处理的是分词后的 token(一个汉字约 1~2 个 token)。上下文窗口由「输入+输出」共享,超出就要分段、摘要或用 RAG。费用 = token 数 × 单价,重复的系统提示每次都在计费,因此出现了 prompt 缓存、历史压缩等省钱手段。会算 token,才谈得上成本控制。

挑战任务

迷你 WSGI 框架

简单+50 XP

就写个极简的 WSGI 路由框架,支持路径路由。

迷你 WSGI 框架
2 个测试用例

课后作业

ASGI 中间件

中等+25 XP

写一个计时中间件,记录每个 HTTP 请求的处理时间。

ASGI 中间件
1 个测试用例