nginx代理websocket负载均衡的核心是正确透传升级头、设置足够长的proxy_read_timeout、确保后端支持长连接,三者缺一不可;必须配置proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade、proxy_set_header connection "upgrade",并选用ip_hash或sticky cookie等会话保持算法。

直接上结论:Nginx做WebSocket负载均衡,核心不是“能不能”,而是proxy_set_header upgrade和proxy_set_header connection这两行配对是否正确、proxy_read_timeout是否够长、后端节点是否真正支持长连接复用——三者缺一不可。
为什么proxy_pass转发后WebSocket总断开?
典型现象是客户端报WebSocket is closed before the connection is established或Nginx日志里出现101 Switching Protocols但随即connection reset by peer。根本原因不是Nginx不支持,而是它默认把WebSocket当普通HTTP处理,没透传协议升级头。
-
proxy_http_version 1.1必须显式设置,不能依赖默认值 -
proxy_set_header upgrade $http_upgrade中变量名必须小写$http_upgrade,写成$HTTP_UPGRADE会失效 -
proxy_set_header connection "upgrade"的值必须是字面量"upgrade",不能写$connection_upgrade(除非你额外定义了map块) - 如果后端服务监听的是
https://或带认证的路径,proxy_pass地址必须与后端实际暴露协议一致,否则握手阶段就失败
least_conn和ip_hash该选哪个?
WebSocket连接建立后不会反复发起新请求,所以轮询(round-robin)会导致同一IP后续帧被分到不同后端,消息丢失。必须用带会话保持能力的算法。
-
least_conn适合后端节点性能差异大、连接数波动剧烈的场景,比如部分节点还跑着HTTP API混部 -
ip_hash最简单可靠,但NAT环境下(如公司内网、运营商级NAT)多个用户共用一个出口IP,会压垮单个后端 - 更稳妥的做法是加
sticky cookie srv_id expires=1h,由Nginx在首次响应里种cookie,后续请求按cookie路由,不受IP变化影响 - 注意:
sticky指令需要nginx-plus或开源版编译时启用ngx_http_sticky_module,非默认模块
proxy_read_timeout设多大才安全?
这个值不是“越长越好”,而是要覆盖业务最长空闲时间+网络抖动缓冲。设太短,Nginx会在心跳间隙主动断连;设太长,又可能拖住连接池资源。
- 若后端应用层心跳间隔是30秒,建议
proxy_read_timeout 90s(3倍),不是24小时 - 金融/交易类系统要求强实时,可设为
60s;IoT设备上报频次低,可放宽到300s -
proxy_send_timeout通常不用调,除非后端写响应特别慢;proxy_connect_timeout保持默认60s足够 - 别漏掉
upstream块里的max_fails=3 fail_timeout=30s,否则某个后端卡死,Nginx仍会持续转发连接过去
WSS(WebSocket over TLS)配置容易忽略什么?
前端用wss://连Nginx,Nginx终止SSL再以http://转发给后端,这是最常见模式。但证书和头信息处理极易出错。
-
ssl_certificate和ssl_certificate_key路径必须绝对准确,Nginx启动时不会报错,但客户端连不上时查error.log会看到no suitable certificate - 必须加
proxy_set_header X-Forwarded-Proto "https",否则后端框架(如Spring Boot)生成重定向URL时可能拼出http://链接 - 如果后端也要求HTTPS(即Nginx不终止SSL),需改用
stream模块做四层代理,此时proxy_*系列指令全部失效 -
server_name要匹配证书SAN,否则浏览器提示证书无效,连接直接拒绝
最常被跳过的点:gowebsocket这类系统依赖Redis做连接寻址,Nginx只管连接分发,不负责消息路由。如果后端节点间没共享Redis或没开启集群模式,即使Nginx配置全对,用户发的消息也可能找不到接收方。











