nginx 实现 websocket 负载均衡的核心在于将 http 请求头中的 upgrade 和 connection 字段透传给后端服务器,并配置反向代理指向一组后端节点。具体做法是在 http 块中定义包含多个后端地址的 upstream 集群,然后在 server 块的 location 中使用 proxy_pass 指向该集群,同时设置 proxy_http_version 1.1、proxy_set_header upgrade $http_upgrade 以及 proxy_set_header connection "upgrade"。这样 nginx 就能在客户端与后端之间建立并保持长连接,实现流量的均匀分发。

如何配置 upstream 集群以支持多节点
要实现负载均衡,必须在 Nginx 配置文件中声明一个 upstream 模块,并在其中列出所有可用的后端 WebSocket 服务地址。Nginx 默认使用轮询(Round Robin)算法,即按顺序将请求分配给不同的后端节点。如果某个节点宕机,Nginx 会自动将其剔除,直到恢复后重新加入。这种配置方式无需修改后端代码,只需确保后端服务监听相同的端口即可。

upstream websocket_backend {
server 192.168.1.10:8080;
server 192.168.1.11:8080;
server 192.168.1.12:8080;
}
上述配置定义了一个名为 websocket_backend 的集群,包含三个后端节点。当客户端发起连接请求时,Nginx 会根据轮询策略选择其中一个节点进行转发。这种配置简单且有效,适用于大多数无状态或会话共享良好的 WebSocket 应用场景。
为什么必须设置 Upgrade 和 Connection 头部
WebSocket 协议依赖于 HTTP 协议的升级机制,因此 Nginx 必须正确传递 Upgrade 和 Connection 请求头,否则握手会失败。默认情况下,Nginx 可能会忽略或修改这些头部,导致后端无法识别升级请求。通过在 location 块中显式设置这两个头部,可以确保 Nginx 将原始请求头原封不动地传递给后端服务器,从而完成协议升级。

server {
listen 80;
server_name ws.example.com;
location /ws/ {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
这段配置展示了完整的 WebSocket 代理设置。其中 proxy_http_version 1.1 是必须的,因为 WebSocket 要求使用 HTTP/1.1 协议。另外两个 proxy_set_header 指令确保了 Upgrade 和 Connection 头部被正确传递。其他头部如 Host、X-Real-IP 和 X-Forwarded-For 用于保留原始请求信息,便于后端日志记录和安全校验。
当后端节点返回非 101 状态码时如何处理
如果后端节点未能成功升级协议,而是返回了如 404 或 500 等错误状态码,Nginx 会将该响应直接返回给客户端,导致 WebSocket 连接建立失败。此时客户端通常会收到一个普通的 HTTP 错误页面,而不是 WebSocket 错误提示。为了提升用户体验,可以在 Nginx 中配置自定义错误页,或者在后端服务中确保所有路径都能正确处理 WebSocket 升级请求。此外,可以通过 proxy_next_upstream 指令让 Nginx 在遇到特定错误时自动尝试下一个后端节点,提高系统的容错能力。











