Nginx stream模块可实现TCP四层负载均衡,适用于MySQL等数据库;需编译启用,配置stream块、upstream及proxy_pass,注意proxy_responses 1和长超时设置,并通过PROXY协议透传客户端IP。

使用 Nginx 的 stream 模块可以实现基于 TCP 的四层负载均衡,适用于 MySQL、PostgreSQL、Redis 等数据库服务。它不解析应用层协议,只转发原始 TCP 流,低延迟、高吞吐,适合数据库连接分发。
启用 stream 模块并配置基础结构
Nginx 默认不编译 stream 模块,需确认安装时已开启(如官方预编译包、或源码编译时加 --with-stream)。配置文件中需在顶层(与 http 同级)定义 stream 块:
- 在
nginx.conf主配置文件末尾或单独引入stream.conf -
stream块内不能嵌套http或其他模块指令 - 支持
upstream、server、proxy_pass、健康检查(需 v1.9.0+)等核心功能
MySQL 四层负载均衡典型配置示例
以下为将客户端对 3306 端口的访问分发至后端三台 MySQL 实例的配置:
stream {
upstream mysql_backend {
# 支持 weight、max_fails、fail_timeout 等参数
server 192.168.1.10:3306 weight=3;
server 192.168.1.11:3306 weight=2;
server 192.168.1.12:3306 backup; # 备用节点,仅当其他不可用时启用
}
<pre class="brush:php;toolbar:false;">server {
listen 3306;
proxy_pass mysql_backend;
proxy_timeout 1h;
proxy_responses 1; # 仅等待首个响应包即建立连接(MySQL握手阶段)
proxy_buffer_size 4k;
# 可选:TCP 层健康检查(v1.11.5+)
health_check interval=3 fails=2 passes=2;
health_check_timeout 1s;
}
}
注意:proxy_responses 1 是关键项,避免 Nginx 等待完整响应而阻塞 MySQL 握手;proxy_timeout 应设为足够长(如 1 小时),防止空闲连接被意外断开。
连接保持与客户端 IP 透传限制
四层代理无法像七层那样改写协议头,因此:
- 真实客户端 IP 不会传递给后端数据库(MySQL 日志、权限控制看到的是 Nginx 本机 IP)
- 若需识别来源,可在 Nginx 所在服务器启用
proxy_protocol,并要求 MySQL 支持 PROXY 协议(如 MySQL 8.0+ 配合bind_address = * + require_secure_transport=OFF并启用proxy-protocol-networks) - 启用方式示例:
listen 3306 proxy_protocol;,后端 MySQL 需配置mysql --proxy-protocol启动并设置对应参数
验证与调试要点
配置完成后务必测试连通性与行为一致性:
- 执行
nginx -t校验语法,再nginx -s reload生效 - 用
mysql -h nginx_ip -P 3306 -u user -p连接,确认可登录且能执行查询 - 查看 Nginx 错误日志(
error_log /var/log/nginx/stream.log warn;)定位连接拒绝、超时等问题 - 用
ss -tuln | grep :3306确认 Nginx 正确监听 TCP 端口 - 关闭某台后端 MySQL,观察是否自动剔除并切到其他节点(依赖健康检查配置)










