Nginx需分层部署:HTTP块处理WebSocket(含Upgrade握手、proxy_http_version 1.1等),stream块处理TCP类服务(如MySQL、游戏协议),二者逻辑隔离、命名分离、健康检查机制不同。

要让 Nginx 同时稳住 WebSocket(七层)和 TCP 类服务(如游戏、MySQL、自定义协议,四层),关键不是“一套配置打天下”,而是分层隔离、各司其职:HTTP 块管 WebSocket,stream 块管纯 TCP,两者互不干扰,共享同一份 Nginx 进程但逻辑完全独立。
WebSocket 必须走 http + upstream + proxy_pass
WebSocket 握手是标准 HTTP Upgrade 请求,必须由 HTTP 模块处理。不能塞进 stream 块,否则会直接失败。
- upstream 块写在 http { } 内,名称唯一,例如
upstream ws_cluster - 启用 least_conn 策略:WebSocket 是长连接,连接数比请求数更能反映真实负载,
least_conn;应放在 upstream 块第一行 - 每个 server 行必须配
max_fails=2 fail_timeout=15s,避免单点卡顿拖垮整条链路 - location 中启用连接复用:
proxy_http_version 1.1;、proxy_set_header Upgrade $http_upgrade;、proxy_set_header Connection "upgrade"; - 务必加
proxy_read_timeout 86400;和proxy_send_timeout 86400;,防止空闲连接被中间设备断开
TCP 四层转发必须走 stream 块,禁用任何 HTTP 相关指令
MySQL、Redis、游戏网关、裸 WebSocket(后端已终结 TLS)等场景,应绕过 HTTP 解析,直通 TCP 流。这里严禁出现 Host、Upgrade、keepalive timeout 等七层概念。
- stream 块必须写在 http 块之外,通常放在 nginx.conf 顶部或底部,与 events、http 并列
- 启用内核级保活:
listen 8080 so_keepalive=on;,比应用心跳更可靠 - 设超时为长周期:
proxy_timeout 1d;(即 86400 秒),匹配业务连接生命周期 - 禁用响应体校验:
proxy_responses 1;,WebSocket/TCP 不需要等 HTTP body 返回 - 若有多 worker 进程,upstream 必须声明
zone tcp_pool 64k;,否则连接统计不同步,least_conn 类行为失效
混合部署时的命名与隔离要点
同一个服务名不能既在 http 块又在 stream 块里出现,Nginx 不报错但行为不可控。必须语义分离,避免混淆。
- WebSocket 集群用
ws_backend、chat_upstream等带 “ws” 或 “http” 含义的名字 - TCP 集群用
tcp_mysql、game_proxy、raw_ws等明确标识四层用途的名字 - proxy_pass 引用时严格区分协议前缀:
http://ws_backendvstcp_mysql(stream 中不加协议头) - SSL 终结建议统一放在入口层:HTTPS/WSS 走 http 块做 TLS 卸载;后端 TCP 若需加密,由 stream + TLS 模块(需编译支持)或下游服务自行处理
健康检查必须双轨并行,不能共用一套逻辑
HTTP 服务健康检查看 HTTP 状态码,TCP 服务看连接建立是否成功——二者探测机制完全不同,混用会导致误判。
- HTTP upstream 中用
health_check interval=3 fails=2 passes=2 match=ws_ready;,配合match块校验 101 状态和 Sec-WebSocket-Accept 头 - stream upstream 中只依赖
max_fails=3 fail_timeout=30s,靠proxy_connect_timeout 2s快速感知连接失败 - 禁止在 stream 块中使用
health_check指令(该指令仅限 http 上游) - 所有 backend 的 /health 接口必须真实反映服务状态,避免返回 200 却无法处理 WebSocket 帧


















