nginx通过stream模块实现tcp多协议统一调度,需版本≥1.9.13并启用--with-stream,配置独立于http块;同一stream块内定义多个upstream与server,按端口隔离mysql、redis等协议,共享超时、健康检查及故障转移能力。

Nginx 实现多协议集群在 TCP 代理下的统一调度,本质是利用 stream 模块作为四层入口,把不同业务的 TCP 流量(如 MySQL、Redis、SSH、Kafka 等)按需分发到各自后端集群,同时共享健康检查、超时控制、故障转移等统一能力,而非为每种协议单独搭一套代理。
必须满足的基础条件
- Nginx 版本 ≥ 1.9.13
- 编译时启用
--with-stream模块(运行nginx -V 2>&1 | grep -o with-stream可确认) - 配置结构严格分离:
stream { ... }块独立于http { ... },不能嵌套
TCP 多协议统一调度的关键配置逻辑
- 所有 TCP 协议代理都定义在同一个
stream块内,但通过不同upstream和server组织实现协议隔离 - 每个协议对应一个独立
upstream(如mysql_cluster、redis_cluster),支持各自权重、失败阈值、备用节点 - 每个协议监听独立端口(如 3306、6379、22),避免端口冲突,也便于防火墙和客户端识别
- 共享全局 stream 级参数(如
worker_connections、proxy_timeout默认值),减少重复配置
典型多协议配置示例(/etc/nginx/nginx.conf)
stream {
# 全局代理超时(可被单个 server 覆盖)
proxy_timeout 60s;
proxy_connect_timeout 3s;
# MySQL 集群
upstream mysql_cluster {
server 10.0.1.10:3306 weight=3 max_fails=2 fail_timeout=30s;
server 10.0.1.11:3306 weight=2 max_fails=2 fail_timeout=30s;
server 10.0.1.12:3306 backup; # 故障时启用
}
# Redis 集群(哨兵或 Cluster 模式前置代理)
upstream redis_cluster {
server 10.0.2.20:6379 max_fails=3 fail_timeout=20s;
server 10.0.2.21:6379 max_fails=3 fail_timeout=20s;
}
# SSH 负载均衡入口
upstream ssh_pool {
server 10.0.3.100:22;
server 10.0.3.101:22;
}
# 各协议监听入口
server {
listen 3306;
proxy_pass mysql_cluster;
}
server {
listen 6379;
proxy_pass redis_cluster;
}
server {
listen 2222;
proxy_pass ssh_pool;
}
}
健康检查与故障转移的实际效果
-
max_fails+fail_timeout组合让 Nginx 在连续失败指定次数后,将节点临时摘除 - 摘除期间新连接不会打到该节点,已有连接不受影响(TCP 连接不中断)
-
backup标记的服务器仅在所有主节点不可用时才参与调度 - 不依赖外部探针,纯基于连接建立是否成功判断健康状态,轻量且可靠
运维与扩展建议
- 把每个协议的
upstream和server拆到独立文件(如/etc/nginx/tcp.d/mysql.conf),用include /etc/nginx/tcp.d/*.conf;加载,便于团队协作和灰度更新 - 对高敏感协议(如数据库),建议搭配
proxy_responses 1(要求至少收到 1 字节响应再认为连接有效),避免 SYN 洪泛误判 - 若需 TLS 透传(如 MySQL over SSL),Nginx 不解密,只做连接转发,确保
proxy_protocol off(除非后端明确支持 PROXY 协议) - 日志方面,
log_format和access_log可在stream块中单独定义,记录客户端 IP、目标地址、连接耗时等,用于链路分析
不复杂但容易忽略。











