upstream块仅用于七层HTTP类协议(如WebSocket),TCP四层转发必须使用独立的stream块;二者是同级配置模块,不可嵌套或混用,需分别在http和stream块中定义对应upstream及server。

upstream 块本身不兼容 TCP 四层转发——它只工作在七层(HTTP/HTTPS/WebSocket/gRPC),而 TCP 四层转发必须用 stream 块。所谓“混合转发”,不是靠一个 upstream 块同时处理 WebSocket 和 TCP,而是通过 http 块内用 upstream 配置 WebSocket(七层) + stream 块外独立配置 TCP(四层),两者并存、各司其职。
明确分工:http 与 stream 必须分离
nginx 的配置结构是严格分层的:http 和 stream 是同级模块,不能嵌套,也不能混用。试图在 http 块里写 stream 配置,或在 stream 块里引用 http 的 upstream,都会导致 nginx 启动失败。
- WebSocket 属于 HTTP 协议升级流程(需处理 Upgrade 头、101 状态码、Connection: upgrade),必须走 http → location → proxy_pass upstream
- TCP 类服务(如游戏服、Redis、MySQL、自定义长连接协议)无 HTTP 语义,必须走 stream → server → proxy_pass
- 同一个域名+端口无法同时承载 WebSocket 和裸 TCP 流量——它们协议本质不同,客户端发起方式也不同(ws:// vs raw TCP socket)
WebSocket 的 upstream 配置要点(七层)
确保后端 WebSocket 服务已自行完成 TLS 终结(或走明文 ws://),并在 nginx http 块中正确声明协议升级逻辑:
- 定义 upstream 指向后端 WebSocket 服务 IP:PORT(例如
upstream ws_api { server 127.0.0.1:8080; }) - server 块中启用
proxy_http_version 1.1,显式透传 Upgrade 相关头:proxy_set_header Upgrade $http_upgrade和proxy_set_header Connection "upgrade" - 禁用缓冲:
proxy_buffering off;设置合理超时:proxy_read_timeout 86400(1天),避免空闲断连 - 不要配
proxy_redirect或重写 Host 头(除非有特殊路由需求),保持原始协议语义完整
TCP 的 stream 配置要点(四层)
为非 HTTP 类长连接服务单独启用 stream 模块,绕过所有应用层解析,直通 TCP 字节流:
- 在 nginx.conf 顶层(events 块之后、http 块之外)添加
stream { ... }块 - 用
upstream定义 TCP 后端组(如upstream game_servers { server 10.0.2.5:7777; }),支持 weight、max_fails 等健康检查参数 - server 块监听专用端口(如
listen 7777 so_keepalive=on;),搭配proxy_timeout 1d和proxy_responses 1 - 不设任何 HTTP 相关指令(Upgrade、Host、X-Forwarded-* 等全部无效且不应出现)
端口与路由协同设计(实际混合落地的关键)
对外暴露多个端口是最清晰、最可靠的方式,让客户端按协议类型主动选择连接入口:
- 前端 Web 页面用
ws://api.example.com:8080/chat→ 走 http 块,经 upstream 代理到 WebSocket 服务 - Unity/Unreal 游戏客户端用
TCP 192.168.1.100:7777→ 走 stream 块,直连 game_servers - DNS 查询走 UDP 53 → 在 stream 块中另配
listen 53 udp;,指向 dns_backend - 避免“同一端口复用 HTTP/WebSocket/TCP”——nginx 不支持,TCP 栈也不允许


















