Nginx Stream模块专用于TCP/UDP四层代理,不解析HTTP等应用层协议,适合MySQL、DNS等场景,具备低延迟、轻量、TLS透传、健康检查和负载均衡能力。

为什么用Stream模块做四层代理
Nginx 的 stream 模块专为 TCP/UDP 流量设计,不解析应用层协议(如 HTTP),只做连接转发。适合数据库、Redis、SSH、游戏服、DNS 等非 HTTP 场景。相比 http 模块,它更轻量、延迟更低、资源占用少,且支持 TLS 透传、健康检查、负载均衡等核心能力。
启用 Stream 模块并配置基础结构
确认 Nginx 编译时已启用 --with-stream(主流发行版包通常默认开启)。在主配置文件(如 /etc/nginx/nginx.conf)顶部添加:
load_module modules/ngx_stream_core_module.so;
然后在文件末尾或独立 include 文件中定义 stream 块:
stream {
include /etc/nginx/stream.d/*.conf;
}
这样便于按服务拆分配置,避免主配置臃肿。
代理 MySQL 流量:真实可用示例
假设后端有两台 MySQL 实例:192.168.10.20:3306 和 192.168.10.21:3306,希望用 Nginx 做负载均衡和连接保护:
# /etc/nginx/stream.d/mysql.conf
upstream mysql_backend {
server 192.168.10.20:3306 max_fails=3 fail_timeout=30s;
server 192.168.10.21:3306 max_fails=3 fail_timeout=30s;
}
<p>server {
listen 3306;
proxy_pass mysql_backend;
proxy_timeout 1h;
proxy_responses 1;
proxy_buffer_size 512k;
}
- proxy_timeout 控制空闲连接超时,MySQL 长连接建议设长些(如 1h)
- proxy_responses 1 表示等待首个响应包再判定连接成功,提升健康检测准确性
- proxy_buffer_size 防止大结果集(如 mysqldump)触发缓冲区溢出
UDP 代理 DNS 查询:简洁可靠方案
DNS 是典型 UDP 服务。以下配置将本机 53 端口请求转发至上游 DNS(如 114.114.114.114 和 8.8.8.8):
# /etc/nginx/stream.d/dns.conf
upstream dns_udp {
server 114.114.114.114:53 weight=5;
server 8.8.8.8:53 weight=3;
}
<p>server {
listen 53 udp;
proxy_pass dns_udp;
proxy_timeout 5s;
proxy_responses 1;
}
- 必须显式加 udp 标识,否则 Nginx 默认走 TCP
- proxy_responses 1 对 UDP 很关键:Nginx 收到第一个响应包即认为本次查询完成,避免超时重发
- UDP 不支持连接复用,每次请求都是独立 datagram,因此无需 keepalive 配置
上线前必做的三件事
- 执行
nginx -t校验语法,特别注意 stream 块不能嵌套在 http 块内 - 确保系统允许绑定特权端口(如 3306、53):要么用 root 启动,要么用
setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx - 防火墙放行对应端口(如
ufw allow 3306或iptables -I INPUT -p tcp --dport 3306 -j ACCEPT)
验证方式简单直接:用 telnet your_nginx_ip 3306 测试 TCP 连通性;用 dig @your_nginx_ip google.com 测试 DNS 转发是否生效。

















