nginx需通过hash $http_sec_websocket_key等握手阶段稳定变量实现websocket sticky session,透传upgrade头、禁用缓冲与超时回收,并配合tcp健康检查保障webrtc信令连接稳定性。

WebRTC信令服务对连接稳定性、低延迟和会话亲和性要求极高,不能简单套用HTTP类负载均衡策略。核心在于:确保同一用户会话的全部WebSocket连接始终路由到同一个后端信令节点,同时维持长连接不被代理中断或超时回收。
必须启用 sticky session 保证会话粘性
信令交换(offer/answer/candidate)是强状态过程,跨节点转发会导致SDP协商失败、ICE候选丢失。Nginx 不支持 WebRTC 原生会话保持,需依赖客户端可识别且服务端可复现的标识:
- 优先使用 hash $connection_upgrade 或 hash $http_sec_websocket_key:这两个变量在WebSocket握手阶段稳定存在,能准确区分不同浏览器连接
- 避免仅用 ip_hash:NAT环境(如企业内网、4G/5G)下大量用户共用出口IP,会导致严重倾斜
- 若前端可控,可在建立WebSocket前通过URL携带唯一roomId(如
wss://signaling.example.com/?room=abc123),后端用 hash $args.room 实现精准路由
显式透传 WebSocket 升级头与保活参数
Nginx默认会缓存、修改或丢弃Upgrade相关头,必须手动声明并放行:
- 设置 proxy_http_version 1.1 和 proxy_set_header Upgrade $http_upgrade
- 添加 proxy_set_header Connection "upgrade"(注意引号,防止被转义)
- 关闭缓冲:proxy_buffering off;禁用请求体读取:proxy_request_buffering off
- 延长超时:proxy_read_timeout 86400(1天),proxy_send_timeout 86400,避免空闲连接被意外关闭
合理划分 upstream 节点健康检查与故障转移
普通HTTP探针无法反映WebSocket服务真实可用性:
- 使用 nginx-plus 或 自定义TCP健康检查脚本(如用nc发送WebSocket握手帧并验证HTTP 101响应)
- 避免配置 max_fails=1 fail_timeout=10s 这类激进策略——单次握手抖动就触发剔除,易造成雪崩
- 推荐配置:max_fails=3 fail_timeout=60s,配合 slow_start=30s 防止节点恢复后瞬时压垮
- 启用 least_conn 作为备用调度策略,当sticky失效时尽量均衡新连接
补充:信令层与媒体层必须物理分离
WebRTC链路中,信令(WebSocket)和媒体流(UDP/RTP/RTCP)是两条独立通路:
- 不要把 STUN/TURN 流量代理进同一 upstream:TURN TCP模式可走Nginx,但UDP流量必须直通或由专用中继服务处理
- 信令 upstream 仅负责
/signalling或/ws路径;媒体路径(如/webrtc)应绕过Nginx,由客户端直连UE实例或TURN服务器 - 若需HTTPS统一入口,Nginx可终止WSS,但后端WebSocket服务必须监听明文WS(非WSS),否则双重TLS带来冗余开销











