nginx 实现 tcp 代理需启用 stream 模块、配置独立 stream 块、使用 upstream/server/proxy_pass 调度,并注意 proxy_responses、proxy_timeout 等关键参数及 proxy 协议透传。

Nginx 实现 TCP 代理的四层负载均衡,本质是绕过 HTTP 协议解析,直接在传输层(TCP)转发原始连接流。它不看数据内容,只依据 IP 和端口做调度,因此低延迟、高吞吐,特别适合 MySQL、Redis 等数据库或长连接服务。
必须启用 stream 模块
Nginx 默认不编译 stream 模块,需确认安装时加了 --with-stream 参数。可通过 nginx -V 2>&1 | grep -o with-stream 验证。若缺失,需重新编译或换用支持该模块的发行版(如官方预编译包)。
配置结构独立于 http 块
所有四层相关配置必须放在顶层 stream { ... } 块中,与 http 同级,不能嵌套在 http 或其他模块内。常见错误就是把 upstream 写进 http 里,会导致配置加载失败。
核心调度逻辑靠 upstream + server + proxy_pass
-
upstream定义后端服务组,支持权重、健康检查、备用节点等参数 -
server块监听客户端请求端口(如listen 3306),并指定转发目标 -
proxy_pass将连接转给 upstream 组,不经过应用层处理
例如 MySQL 负载均衡:
stream {
upstream mysql_cluster {
server 192.168.1.10:3306 weight=3;
server 192.168.1.11:3306 weight=2;
server 192.168.1.12:3306 backup;
}
server {
listen 3306;
proxy_pass mysql_cluster;
proxy_timeout 1h;
proxy_responses 1;
proxy_connect_timeout 5s;
}
}
关键参数不可省略
-
proxy_responses 1:MySQL 握手只需第一个响应包,设为 1 可避免阻塞连接建立 -
proxy_timeout应设为较大值(如1h),防止空闲数据库连接被代理层断开 -
proxy_connect_timeout控制 Nginx 连接后端的超时,一般设为1–5s即可
调度算法按场景选
- 轮询(默认):适合后端性能相近、无状态服务
-
least_conn:优先分发到当前连接数最少的节点,对长连接更友好 -
hash $remote_addr consistent:Redis 场景推荐,保证同一客户端始终打到同一后端,维持连接上下文 -
weight:显式控制流量比例,适配不同规格的数据库实例
真实客户端 IP 无法自动透传
四层代理不改写协议头,后端看到的是 Nginx 本机 IP。如需识别来源,必须配合 PROXY 协议:
- Nginx 端开启
listen 3306 proxy_protocol; - 后端 MySQL/Redis 需支持并启用 PROXY 协议(如 MySQL 8.0+ 配置
require_secure_transport=OFF并设置proxy-protocol-networks)
不复杂但容易忽略细节。











