Nginx Stream模块实战:香港服务器TCP/UDP四层负载均衡与MySQL/Redis代理配置
Nginx 广为人知的是 HTTP 七层代理,但它的 Stream 模块同样强大——可以在 TCP/UDP 四层对任意协议进行负载均衡和代理,无需理解上层协议内容。MySQL 读写分离代理、Redis Sentinel 的透明切换、游戏 UDP 服务器集群、数据库连接池前置代理,这些场景都能用 Nginx Stream 优雅解决,且几乎零额外资源开销。
一、Stream 模块 vs 七层 HTTP 代理
| 维度 | HTTP 代理(http block) | Stream 模块(stream block) |
|---|---|---|
| 工作层级 | L7(应用层,理解 HTTP) | L4(传输层,透明转发字节流) |
| 支持协议 | HTTP/HTTPS/WebSocket | 任意 TCP/UDP 协议 |
| 内容检查 | 可以读取/修改 HTTP 头 | 不解析内容,透明转发 |
| 典型用途 | Web 应用反向代理 | MySQL/Redis/游戏/DNS 代理 |
| SSL 终结 | ✅ | ✅(SNI 分发) |
| 性能开销 | 中 | 极低(近乎零开销) |
二、检查并编译 Stream 模块
<code"># 检查当前 Nginx 是否包含 Stream 模块 nginx -V 2>&1 | grep -o 'with-stream[^ ]*' # 输出 --with-stream 说明已包含 # Ubuntu 安装带 Stream 的 Nginx apt install -y nginx-full # nginx-full 包含 Stream 模块 # 或 apt install -y nginx-extras
<code"># /etc/nginx/nginx.conf 顶层结构
# Stream 块与 http 块同级,不在 http 内部
# ... events 块 ...
http {
# 普通 HTTP 配置
}
# Stream 模块配置(TCP/UDP 代理)
stream {
# 日志格式
log_format stream_basic '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr"';
access_log /var/log/nginx/stream.log stream_basic;
include /etc/nginx/stream.d/*.conf;
}三、MySQL 读写分离代理
<code"># /etc/nginx/stream.d/mysql.conf
upstream mysql_write {
server 10.0.0.1:3306; # 主库(写)
}
upstream mysql_read {
server 10.0.0.1:3306 weight=1; # 主库也可以读
server 10.0.0.2:3306 weight=3; # 从库1(读,权重更高)
server 10.0.0.3:3306 weight=3; # 从库2(读)
# 健康检查(Nginx Plus 功能,开源版用 max_fails)
# health_check interval=10 fails=3 passes=2;
}
# 写操作端口 3307 → 主库
server {
listen 3307;
proxy_pass mysql_write;
proxy_connect_timeout 5s;
proxy_timeout 300s; # MySQL 长连接超时
# 只允许应用服务器连接(IP 白名单)
allow 10.0.0.0/24;
deny all;
}
# 读操作端口 3308 → 从库集群
server {
listen 3308;
proxy_pass mysql_read;
proxy_connect_timeout 5s;
proxy_timeout 300s;
allow 10.0.0.0/24;
deny all;
}<code"># 应用配置使用读写分离连接字符串(以 Python SQLAlchemy 为例)
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
# 写操作引擎(连接到 Nginx 写代理端口)
write_engine = create_engine(
"mysql+pymysql://user:pass@nginx-proxy:3307/mydb",
pool_size=10, pool_recycle=300
)
# 读操作引擎(连接到 Nginx 读代理端口)
read_engine = create_engine(
"mysql+pymysql://user:pass@nginx-proxy:3308/mydb",
pool_size=20, pool_recycle=300
)四、Redis 主从透明代理
<code"># /etc/nginx/stream.d/redis.conf
upstream redis_master {
server 10.0.0.4:6379; # Redis 主节点
}
upstream redis_slaves {
server 10.0.0.5:6379; # 从节点1
server 10.0.0.6:6379; # 从节点2
least_conn; # 最少连接数调度
}
# 写操作(SET/DEL 等)→ 主节点
server {
listen 6380;
proxy_pass redis_master;
proxy_connect_timeout 3s;
proxy_timeout 60s;
allow 10.0.0.0/24;
deny all;
}
# 读操作(GET/KEYS 等)→ 从节点
server {
listen 6381;
proxy_pass redis_slaves;
proxy_connect_timeout 3s;
proxy_timeout 60s;
allow 10.0.0.0/24;
deny all;
}五、TCP 负载均衡(游戏服务器)
<code"># /etc/nginx/stream.d/game.conf
upstream game_servers {
server 10.0.1.1:7777 weight=1;
server 10.0.1.2:7777 weight=1;
server 10.0.1.3:7777 weight=1;
# 会话保持:同一个客户端 IP 总是连接同一台游戏服务器
hash $remote_addr consistent;
}
server {
listen 7777;
proxy_pass game_servers;
proxy_connect_timeout 5s;
proxy_timeout 3600s; # 游戏长连接,超时设置长一些
# 限制单 IP 并发连接数(防 CC 攻击)
limit_conn_zone $remote_addr zone=game_conn:10m;
limit_conn game_conn 5; # 每个 IP 最多5个并发连接
}六、UDP 负载均衡(DNS/游戏 UDP)
<code"># /etc/nginx/stream.d/udp.conf
upstream dns_servers {
server 8.8.8.8:53;
server 1.1.1.1:53;
}
server {
listen 53 udp reuseport; # UDP 协议,reuseport 提升性能
proxy_pass dns_servers;
proxy_timeout 3s; # UDP 超时较短
proxy_responses 1; # 每个请求期望1个响应
# UDP 游戏服务器(多个响应)
# proxy_responses 0; # 0 = 不限制响应数
}七、SNI 分发(同端口多域名 TLS)
<code"># /etc/nginx/stream.d/tls-sni.conf
# 根据 TLS 握手的 SNI 信息将流量分发到不同后端
# 无需解密,保持端对端加密
map $ssl_preread_server_name $backend {
api.yourdomain.com 10.0.0.10:443; # API 服务器
app.yourdomain.com 10.0.0.11:443; # 应用服务器
db-admin.yourdomain.com 10.0.0.12:443; # 数据库管理
default 10.0.0.10:443; # 默认
}
server {
listen 443;
ssl_preread on; # 读取 SNI,不解密
proxy_pass $backend;
proxy_protocol on; # 传递真实客户端 IP
}八、连接数监控
<code"># 查看 Nginx Stream 当前连接状态
# 在 http 块中开启状态页
http {
server {
listen 8888;
location /nginx_status {
stub_status on;
allow 127.0.0.1;
deny all;
}
}
}
# 实时监控 TCP 连接
ss -tn state established | awk '{print $5}' | \
grep -E ':3307|:3308|:6380|:7777' | \
sort | uniq -c | sort -rn九、总结
Nginx Stream 以极低的资源开销实现了 MySQL 读写分离路由、Redis 主从代理、游戏 UDP 负载均衡等场景,是架构设计中的”万能胶水层”。香港服务器上一台 Nginx 实例同时承担 HTTP 七层代理和 TCP/UDP 四层代理,统一管理所有流量入口,运维复杂度大幅降低。