要让upstream集群真正支持WebRTC信令长连接调度,核心是启用WebSocket协议透传与保活、确保连接亲和性(如hash $cookie.io)、并协同信令服务管理生命周期,同时明确TURN/STUN流量不走upstream。

要让 upstream 集群真正支持 WebRTC 信令长连接调度,核心不是简单加几台机器,而是围绕“连接不中断、信令不乱序、状态可维持”三个目标重构 Nginx 的代理逻辑。WebRTC 信令(如 Offer/Answer/ICE Candidate)虽走 WebSocket,但对连接稳定性极其敏感——一次意外断连就可能让整个 P2P 协商失败,最终表现为黑屏、无响应或 ICE connection failed。
必须启用 WebSocket 协议透传与连接保活
这是最基础也最容易漏掉的一环。Nginx 默认按 HTTP 短连接处理,会主动关闭空闲连接,直接杀死信令链路:
-
强制使用 HTTP/1.1:添加
proxy_http_version 1.1;,否则无法触发协议升级 -
透传 Upgrade 请求头:用
proxy_set_header Upgrade $http_upgrade;把客户端的升级意图传给后端 -
显式声明 Connection 行为:设为
proxy_set_header Connection "upgrade";,不能写成变量或留空 -
延长超时时间:
proxy_read_timeout 86400;(24 小时),避免静默期断连;proxy_send_timeout同理
确保同一用户始终落在同一信令节点
信令服务器(如基于 Socket.IO 或 ws 的 Node.js 服务)本身不共享内存或会话状态。若用户 A 的 Offer 发到 node-1,Answer 却被负载到 node-2,就会丢失协商结果:
- 用
ip_hash最简单:适合公网 IP 相对稳定的场景(如企业内网、固定出口) - 更推荐
hash $cookie.io; keepalive 32;:前端首次连接时由信令服务 Set-Cookie 返回唯一 io sessionId,后续请求自动绑定节点 - 避免用
least_conn或random:它们破坏连接亲和性,信令流会随机漂移
配合信令服务做连接生命周期协同
upstream 只管转发,真正的连接管理在信令服务端。Nginx 需要和它“步调一致”:
- 开启
proxy_ignore_client_abort on;:防止用户切页、刷新导致 Nginx 主动断开后端连接 - 配置
proxy_buffering off;:信令是小包高频交互,缓冲反而引入延迟和乱序 - 后端健康检查建议用
GET /health?ts=xxx,而非依赖 WebSocket 连接数——因为长连接本身不反映业务可用性 - 若用 Socket.IO,注意其默认路径是
/socket.io/,upstream 路由需精确匹配,避免被静态规则截断
补充:TURN/STUN 流量不走 upstream
特别注意:WebRTC 媒体流(音视频)和 ICE Candidate 中的 UDP 数据,不经过信令服务器,也不走 Nginx upstream。它们是点对点直连,或经独立部署的 TURN 服务器(如 coturn)中继。upstream 集群只负责信令层的 WebSocket 流量调度。别试图用 Nginx 转发 UDP 或做 STUN/TURN 代理——那属于完全不同的网络层级。











