Nginx stream模块支持TCP/UDP四层代理,适用于MySQL、Redis等数据库负载均衡,不解析应用层协议,低延迟高吞吐;需编译时启用--with-stream,配置在全局stream块中,注意超时、连接优化、健康检查及安全控制。

Nginx 的 stream 模块支持 TCP/UDP 四层代理,非常适合 MySQL、Redis 等基于 TCP 的数据库服务做负载均衡。它不解析应用层协议(如 SQL 或 Redis 命令),只转发原始连接,低延迟、高吞吐,且无需修改客户端配置。
启用 stream 模块并配置基础结构
Nginx 默认不编译 stream 模块,需确认安装时已开启:--with-stream。可通过 nginx -V 2>&1 | grep -o with-stream 验证。配置需在全局层级(nginx.conf 最外层)定义,不能放在 http 块内。
基本结构如下:
}stream {
upstream mysql_backend {
server 192.168.1.10:3306 weight=5;
server 192.168.1.11:3306 weight=5;
least_conn; # 可选:按当前连接数调度
}
<pre class="brush:php;toolbar:false;">server {
listen 3306;
proxy_pass mysql_backend;
proxy_timeout 1h;
proxy_responses 1; # MySQL 握手只需 1 次响应
}
适配 MySQL 连接的关键细节
MySQL 客户端连接建立后会复用长连接,Nginx stream 需保持连接稳定,并正确处理握手与超时:
-
关闭 Nagle 算法:在
server块中添加proxy_buffering off;和tcp_nodelay on;,减少小包延迟 -
设置合理超时:MySQL 默认 wait_timeout=28800 秒,建议
proxy_timeout设为略大于该值(如 30000s),避免 Nginx 主动断连 -
健康检查(需 Nginx Plus 或开源版配合脚本):开源版不支持
stream原生健康检查,可用tcp_check脚本 +health_check指令(仅 Plus),或通过外部探活+动态 reload 实现
适配 Redis 连接的注意事项
Redis 协议简单(RESP),但对连接粘性和命令原子性敏感,尤其在使用连接池时:
-
禁用连接复用:Redis 客户端通常自行管理连接池,Nginx 不应做连接合并,确保
proxy_protocol off;(除非后端明确支持 PROXY 协议) -
推荐使用 IP Hash 或 Least Conn:避免单个客户端请求被分散到多个 Redis 实例(影响 pipeline 和事务语义),
ip_hash;可保障同一客户端 IP 总打到同一后端 - 注意 AUTH 和 SELECT 命令兼容性:stream 层不干预协议,只要后端 Redis 已统一配置密码和 db,默认可透传;若后端分片策略不同,需在应用层控制 key 分布
安全与可观测性补充建议
四层代理不校验账号密码,安全依赖网络隔离与访问控制:
- 用
allow/deny限制接入 IP:allow 10.0.0.0/8; deny all;放在server块内 - 开启日志记录连接信息:
access_log /var/log/nginx/stream-mysql.log;,格式需自定义(默认无 stream 日志变量,可用$remote_addr、$status、$session_time等) - 监控连接数与错误码:
stub_status不支持 stream,改用nginx -T | grep -A 5 'stream {'配合系统级指标(如ss -s、netstat)或 Prometheus + nginx-lua-prometheus(需 Lua 模块扩展)











