Nginx 不支持 WebSocket 流量原生镜像,仅可在握手阶段对 Upgrade 请求做镜像用于审计或鉴权,后续帧数据需在应用层或专用网关实现复制,连接备份应依赖会话外置与客户端重连机制。

Nginx 本身不支持 WebSocket 流量的原生镜像(mirror)或备份转发,因为 WebSocket 是长连接、双向通信协议,而 Nginx 的 mirror 指令仅适用于 HTTP 短连接请求(如 GET/POST),无法复制升级后的 WebSocket 连接帧流。但可通过架构设计和配置组合,实现接近“流量镜像”与“连接备份”的效果——核心在于连接层分流 + 应用层协同,而非单纯靠 Nginx 单点镜像。
WebSocket 连接建立阶段可做请求级镜像
在客户端发起 WebSocket 升级请求(Upgrade: websocket)时,该请求仍是标准 HTTP 请求,Nginx 可对其做镜像处理,用于日志审计、鉴权预检或轻量级路由决策:
- 使用
mirror指令将 Upgrade 请求(不含 body)异步转发到旁路服务,例如鉴权网关或审计系统 - 镜像请求不影响主连接流程,主连接仍按正常 proxy_pass 转发至后端 WebSocket 服务器
- 注意:镜像仅触发一次(握手阶段),不镜像后续的二进制/文本帧数据
真正的流量复制需依赖应用层或中间件
若需实时复制 WebSocket 数据帧(如用于监控、回放、灾备同步),必须在业务逻辑层或独立代理层实现,Nginx 不具备帧级复制能力:
- 推荐方案:在 WebSocket 后端服务中集成双写逻辑(如收到 client 消息后,同时发给主业务节点和备份/分析节点)
- 替代方案:使用专用 WebSocket 网关(如 Envoy、Traefik 或自研 Go/Node.js 中间件),支持消息广播、镜像订阅等高级路由能力
- 避免误区:不要尝试用 Nginx 的
split_clients或upstream ip_hash实现“连接备份”,这只能做负载均衡,无法保证状态同步
高可用备份应聚焦连接管理与会话恢复
WebSocket 无状态连接天然难以“热备份”,更务实的做法是提升容错能力与快速恢复能力:
- 启用 Nginx 的健康检查(
health_check)和主动探测,配合proxy_next_upstream自动故障转移 - 后端服务需支持会话状态外置(如存入 Redis),使新节点接管时能恢复上下文
- 客户端加入重连机制(带退避策略),配合 Nginx 设置合理超时:
proxy_read_timeout 86400、proxy_send_timeout 86400
最小可行配置示例(含握手镜像 + 连接代理)
以下配置实现:WebSocket 握手请求镜像至 audit 服务;主连接稳定代理至 ws_backend;并启用连接保持与超时优化:
upstream ws_backend {
server 127.0.0.1:8080;
keepalive 32;
}
<p>upstream ws_audit {
server 127.0.0.1:9090;
}</p><p>server {
listen 80;
location /ws/ {</p><h1>镜像握手请求(仅 HTTP 阶段)</h1><pre class="brush:php;toolbar:false;"> mirror /mirror;
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_pass http://ws_backend;
# 长连接超时设置
proxy_read_timeout 86400;
proxy_send_timeout 86400;
}
location = /mirror {
internal;
proxy_pass http://ws_audit$request_uri;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}}
不复杂但容易忽略:镜像只是握手快照,真要复制数据流得让后端说话——Nginx 是门卫,不是录音机。











