websocket反向代理需配置least_conn负载均衡、透传upgrade/connection头、延长超时、禁用缓冲及透传客户端ip。

轮询本身不是WebSocket长连接的理想方案,但如果你的后端服务是无状态或已自行处理会话同步(比如通过Redis共享连接状态),轮询可以作为起点。关键在于:Nginx必须正确透传协议升级请求,并维持连接不被误断——否则轮询只是“表面配置”,实际连接根本建不起来或频繁中断。
基础轮询结构要加keepalive和least_conn
单纯写upstream { server a; server b; }是不够的。WebSocket连接生命周期长,轮询若不配合连接感知策略,容易把新连接都压到刚重启或低负载的节点上,造成雪崩。建议用least_conn替代纯轮询,它会把新连接优先分发给当前活跃连接数最少的后端:
- upstream websocket_backend {
- server 192.168.1.100:8080 max_fails=3 fail_timeout=30s;
- server 192.168.1.101:8080 max_fails=3 fail_timeout=30s;
- least_conn;
- keepalive 32;
- }
必须显式处理Upgrade和Connection头
Nginx默认会清理或重写Connection头,而WebSocket握手依赖Upgrade: websocket和Connection: Upgrade这两个字段。不配置就等于拒绝升级:
- 在http块顶部添加映射,让Nginx动态设置Connection值:
- map $http_upgrade $connection_upgrade {
- default upgrade;
- '' close;
- }
- 在location中使用:
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection $connection_upgrade;
超时时间必须拉长,且禁用缓冲
WebSocket连接空闲时没有HTTP请求/响应,Nginx默认60秒proxy_read_timeout会直接断开。同时,代理缓冲会导致消息延迟或粘包:
- proxy_read_timeout 3600;
- proxy_send_timeout 3600;
- proxy_connect_timeout 30;
- proxy_buffering off;
- proxy_cache off;
客户端IP和协议头要透传
后端做鉴权、限流、日志追踪时需要原始信息,不能只靠$remote_addr(那是Nginx本机IP):
- proxy_set_header Host $host;
- proxy_set_header X-Real-IP $remote_addr;
- proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
- proxy_set_header X-Forwarded-Proto $scheme;











