必须用uvicorn等原生asgi服务器托管fastapi等应用,nginx需配置proxy_http_version 1.1、upgrade/connection头透传websocket,并对齐keepalive超时参数,否则会连接中断或502错误。

要让 Nginx 正确代理 ASGI 异步应用(如 Django Channels、FastAPI 或 Starlette),必须同时满足两个核心条件:一是 Nginx 能透传 WebSocket 和流式请求所需的协议升级机制;二是后端 ASGI 服务器(如 Uvicorn)本身支持长连接并稳定运行。WSGI 服务器(如 Gunicorn)不能真正处理 ASGI,强行使用会导致连接中断或 502 错误。
必须用 ASGI 服务器,不能用 Gunicorn 直接跑
ASGI 应用(如 asgi.py)需要原生支持事件循环和多消息生命周期的服务器。Gunicorn 是 WSGI 服务器,只理解单次请求-响应模型,即使加了 --worker-class eventlet,也只是协程模拟,并不实现 ASGI 的 scope、receive、send 三元组规范。结果就是 WebSocket 连接建立后立刻断开,或 SSE 流被截断。
- 推荐使用 Uvicorn:它基于 uvloop,原生实现 ASGI,生产验证充分
- 启动命令示例:
uvicorn myapp.asgi:application --host 127.0.0.1 --port 8000 --workers 4 - 切勿将 Uvicorn 暴露给公网——它不是反向代理,缺少 SSL 终止、限速、缓存等能力
Nginx 必须显式支持 Upgrade 和 HTTP/1.1 长连接
Nginx 默认把 WebSocket 请求当作普通 HTTP 处理,若不配置透传逻辑,会直接返回 400 或静默关闭连接。关键配置必须全部到位:
-
proxy_http_version 1.1;:强制使用支持长连接的协议版本 proxy_set_header Connection "upgrade";proxy_set_header Upgrade $http_upgrade;-
proxy_set_header Connection "";:清空客户端可能带的Connection: close干扰头 -
proxy_pass http://127.0.0.1:8000;:注意末尾不加/,避免路径重写异常
上下游长连接参数需对齐
仅配 Nginx 不够,后端 Uvicorn 和上游客户端(如浏览器)的超时、连接池也要协同:
- Nginx 客户端侧:
keepalive_timeout 300s;、keepalive_requests 10000; - Nginx 后端侧(upstream 块中):
keepalive 32;,且确保worker_processes × keepalive ≤ 后端总连接池 × 0.7 - Uvicorn 启动时不要设过短的
--timeout-keep-alive(默认 5 秒太短,建议调至 60–120 秒) - 后端服务(如 Django Channels)需启用 Redis 等广播后端,否则多 worker 下 WebSocket 无法跨进程通信
验证是否生效的三个实操方法
光看配置没用,得观察真实行为:
- 执行
ss -tnp | grep :8000,确认有稳定存在的ESTABLISHED连接,而非瞬时创建又消失 - 打开浏览器开发者工具,发起
ws://连接,检查 Network → WS → Frames 是否持续收发消息,无自动关闭 - 抓包(如 Wireshark 或
tcpdump)确认 Nginx 发往后端的请求头不含Connection: close,且多个请求复用同一 TCP 流
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











