要让upstream集群稳定承载大规模WebSocket长连接,核心是Nginx理解并尊重其生命周期:需配置keepalive复用连接、禁用默认健康检查、采用一致性哈希路由、设置超时为7天、禁用缓冲并增强可观测性。

必须启用的 upstream 基础能力
upstream 本身不处理协议,但它是流量分发的起点。要支撑万级+长连接,需显式开启连接复用与状态感知:
-
keepalive 指令不可省略:每个 worker 进程与后端节点维持固定数量空闲长连接(如
keepalive 32;),避免每次新连接都重建 TCP,大幅降低 handshake 开销 -
keepalive_requests 和 keepalive_timeout 要匹配业务场景:例如设为
keepalive_requests 1000; keepalive_timeout 60s;,既防连接无限堆积,又避免频繁断开重连 -
server 行加
max_fails=0 fail_timeout=30s:WebSocket 连接是“静默型”——无心跳时后端不主动上报健康状态,Nginx 默认探活机制会误判节点宕机;设为 0 可禁用自动摘除,改由业务层(如 gRPC 心跳或 Redis 在线状态)统一管理可用性
负载策略选型:一致性哈希比轮询更稳
对 WebSocket 来说,“同一个用户始终落到同一节点”比“平均分配”更重要。否则用户登录、房间加入、私聊上下文等状态分散在多个节点,就得强依赖 Redis 广播或跨节点查询,延迟和复杂度陡增。
-
用
hash $remote_addr consistent;或hash $http_x_user_id consistent;:前者基于客户端 IP(适合内网或可信网络),后者建议在鉴权后由网关注入真实用户 ID,实现精准路由 -
避免使用
ip_hash:它不支持动态扩缩容,新增节点会导致大量哈希重分布,引发用户强制重连 -
backup 节点要带 weight=1 且明确标注:例如
server backup.example.com:8080 backup weight=1;,确保仅在全部主节点不可达时才启用,防止降级逻辑混乱
超时与缓冲区:按“天”而非“秒”设计
WebSocket 连接可能持续数小时甚至数天。Nginx 默认以 HTTP 短连接思维设置超时,必须彻底覆盖:
- proxy_read_timeout 和 proxy_send_timeout 设为 604800(7 天):只要后端有响应(哪怕只是 ping),连接就应保持;设太小会导致静默期被单方面关闭
- proxy_buffering off;:禁用响应缓冲,避免 Nginx 缓存未完成的消息帧,造成客户端收包延迟或粘包
- proxy_buffers 8 16k; proxy_busy_buffers_size 32k;:适当扩大缓冲区,应对突发大消息(如群公告、文件元数据推送)
安全与可观测性:不能只靠“通不通”
企业级环境要求可定位、可审计、可限流:
-
在 upstream 外层加 map 实现 Upgrade 安全透传:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
} - 开启 access_log 自定义日志格式,记录 $upstream_addr 和 $upstream_response_time:能快速识别某类用户是否总被分到慢节点,或某台后端是否响应异常
- 配合 limit_conn zone=addr:10m 限制单 IP 连接数:防止恶意扫描或脚本滥占连接资源,保护集群整体稳定性


















