Nginx Stream 代理配置全解析:TCP/UDP 流量转发及常见问题排查
Nginx 除了可以处理 HTTP 代理,还可以用于 TCP/UDP 流量转发,适用于 数据库代理(MySQL、PostgreSQL)、Redis 负载均衡、WebSocket 代理、游戏服务器流量分发 等场景。相比 HAProxy,Nginx 配置更加灵活,并且可以结合 stream 模块进行高效的 TCP/UDP 代理。
本篇文章将带你深入了解 Nginx Stream 代理的配置方法、负载均衡策略,以及常见问题的解决方案,帮助你优化流量转发,提高系统稳定性。
1. 启用 Nginx Stream 模块
默认情况下,Nginx 并不会自动启用 stream 模块,需要在编译时添加支持(如果你使用的是主流 Linux 发行版,如 Ubuntu、CentOS,自带的 Nginx 版本通常已经包含 stream 模块)。
• 检查是否支持 stream 模块
nginx -V 2>&1 | grep stream
如果输出包含 --with-stream,说明 stream 模块已启用,否则需要重新编译 Nginx。
2. 配置 TCP/UDP 代理
Nginx stream 模块的基本用法如下:
stream {
upstream mysql_backend {
server 192.168.1.10:3306;
server 192.168.1.11:3306 backup;
}server {
listen 3306;
proxy_pass mysql_backend;
}
}
📌 示例解析:
• 监听 3306 端口,将 MySQL 请求转发到 mysql_backend 组
• upstream 组中定义了两台 MySQL 服务器(主服务器 + 备用服务器)
• 当主服务器宕机时,Nginx 会自动切换到 backup 服务器
📌 适用场景:
• MySQL 读写分离
• Redis 代理(监听 6379,转发到 Redis 集群)
• TCP WebSocket 代理
3. 配置 UDP 代理(DNS、RTP、游戏服务器)
UDP 代理的方式类似于 TCP,只需要添加 udp 关键字:
stream {
upstream dns_backend {
server 8.8.8.8:53;
server 8.8.4.4:53;
}server {
listen 53 udp;
proxy_pass dns_backend;
}
}
📌 示例解析:
• 监听 53 端口(DNS 请求),并将流量转发至 Google DNS 服务器
• 适用于 DNS 代理、视频流、VoIP、游戏服务器等 UDP 场景
4. 负载均衡策略
在 stream 代理中,Nginx 提供了多种负载均衡方式:
负载均衡策略 | 说明 |
---|---|
round-robin(默认) | 轮询分发请求 |
least_conn | 选择连接最少的服务器 |
hash $remote_addr | 按客户端 IP 进行哈希,适用于长连接 |
示例:使用最少连接负载均衡 Redis
stream {
upstream redis_backend {
least_conn;
server 192.168.1.10:6379;
server 192.168.1.11:6379;
}server {
listen 6379;
proxy_pass redis_backend;
}
}
📌 适用场景:
• least_conn 适用于 长连接服务(MySQL、Redis、PostgreSQL)
• hash 适用于 确保相同用户访问同一后端服务器
5. TLS 加密(安全性增强)
如果要在 stream 代理中启用 TLS,需要添加 ssl_preread 配置。
stream {
server {
listen 443 ssl;
proxy_pass backend_https;
ssl_preread on;
}upstream backend_https {
server 192.168.1.10:443;
server 192.168.1.11:443;
}
}
📌 适用场景:
• SSL 负载均衡
• HTTPS WebSocket 代理
• 加密数据库通信
6. 常见问题及解决方案
❌ 问题 1:Nginx 启动时报 unknown directive "stream"
💡 原因:Nginx 未编译 stream 模块
🔹 解决方案:重新安装包含 stream 模块的 Nginx
# Ubuntu/Debian
apt install nginx-full -y# CentOS
yum install nginx-mod-stream -y
❌ 问题 2:TCP 代理后端连接失败
💡 可能原因:
1. Nginx 没有访问后端服务器的权限(检查 firewalld / iptables)
2. 后端端口未开放(netstat -tulnp | grep 3306)
3. SELinux 限制了端口访问(setenforce 0 关闭 SELinux)
🔹 解决方案:
firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --reload
❌ 问题 3:负载均衡策略不生效
💡 可能原因:
1. least_conn 只在 长连接 场景生效(MySQL、Redis)
2. hash $remote_addr 需要确保 客户端 IP 正确传递
stream {
upstream backend {
least_conn; # 确保启用了 least_conn
}
}
❌ 问题 4:WebSocket 代理失败
💡 可能原因:
1. 未正确传递 Upgrade 头
2. 未启用 proxy_protocol
🔹 解决方案:
stream {
server {
listen 443 proxy_protocol;
proxy_pass backend;
ssl_preread on;
}
}
总结
🔹 Nginx stream 模块 可用于 TCP/UDP 代理、数据库负载均衡、游戏服务器代理
🔹 支持 least_conn / hash 负载均衡策略
🔹 可以结合 ssl_preread 进行 TLS 代理
🔹 遇到 unknown directive "stream" 错误?检查 Nginx 是否编译了 stream 模块!
🔹 遇到连接失败?检查 iptables / firewalld / SELinux
如果你在 Nginx Stream 配置中遇到了问题,欢迎留言讨论!🚀