别只拿Nginx当Web服务器了!手把手教你用stream模块搞定MySQL远程访问和DNS负载均衡

张开发
2026/4/21 13:01:22 15 分钟阅读

分享文章

别只拿Nginx当Web服务器了!手把手教你用stream模块搞定MySQL远程访问和DNS负载均衡
别只拿Nginx当Web服务器了手把手教你用stream模块搞定MySQL远程访问和DNS负载均衡当大多数人提起Nginx时脑海中浮现的往往是那个处理HTTP请求的反向代理神器。但今天我们要聊的是Nginx鲜为人知的另一面——作为四层网络代理的强悍能力。想象一下开发团队急需访问生产数据库却受限于IP白名单或者你的DNS服务需要实现高可用却不想引入复杂架构。这些看似棘手的问题其实用Nginx的stream模块就能优雅解决。1. 为什么需要四层代理传统方案的痛点与革新在真实的运维场景中网络访问限制就像无形的围墙。以MySQL数据库为例安全规范通常要求严格限制访问源IP。传统做法要么是频繁修改白名单伴随着审计麻烦要么搭建跳板机增加了单点故障风险。而UDP服务如DNS的负载均衡往往需要专门部署Keepalived或商用硬件设备。四层代理的独特优势协议无关性直接工作在传输层可处理任意TCP/UDP协议性能无损不像七层代理需要解析应用层协议转发效率更高配置简洁与Nginx的HTTP配置相似学习成本低资源复用利用现有Nginx实例无需额外部署中间件实际案例某金融项目因合规要求生产环境MySQL只允许应用服务器IP访问。通过Nginx stream模块我们在不修改数据库白名单的情况下为审计人员提供了安全访问通道同时完整记录了所有访问日志。2. 环境准备编译与模块加载实战默认安装的Nginx往往不带stream模块支持我们需要从源码编译开始。以下是在CentOS 7上的完整操作流程# 安装编译依赖 yum install -y gcc pcre-devel zlib-devel openssl-devel # 下载源码以1.22.0版本为例 wget https://nginx.org/download/nginx-1.22.0.tar.gz tar zxvf nginx-1.22.0.tar.gz cd nginx-1.22.0 # 编译时加入stream模块 ./configure --with-stream --with-stream_ssl_module make make install常见问题排查报错nginx: [emerg] unknown directive stream原因动态模块未加载解决在nginx.conf顶部添加load_module modules/ngx_stream_module.so;模块验证命令nginx -V 21 | grep -o with-stream3. 核心配置详解从MySQL代理到DNS负载均衡3.1 MySQL端口转发实战在/etc/nginx/nginx.conf中添加与http块平级的stream配置段stream { log_format mysql_proxy $remote_addr [$time_local] $protocol $status $bytes_sent $bytes_received $session_time $upstream_addr; server { listen 3306; proxy_connect_timeout 3s; proxy_timeout 1h; # 适合长连接场景 proxy_pass db_cluster; } upstream db_cluster { server 10.0.0.101:3306 weight5; server 10.0.0.102:3306; } }关键参数解析参数说明生产环境建议值proxy_connect_timeout连接后端超时3-5秒proxy_timeout连接最大保持时间按业务调整reuseport启用SO_REUSEPORT高并发场景建议开启3.2 DNS负载均衡配置技巧针对UDP协议的特殊处理upstream dns_servers { hash $remote_addr consistent; # 保持会话一致性 server 192.168.1.10:53; server 192.168.1.11:53; } server { listen 53 udp reuseport; # 关键参数 proxy_responses 1; # 预期接收的响应数 proxy_timeout 2s; proxy_pass dns_servers; }UDP配置注意事项必须显式声明udp参数reuseport提升多核处理效率proxy_responses控制响应包数量超时设置应短于TCP场景4. 高级技巧与性能调优4.1 流量监控方案在stream块中配置访问日志access_log /var/log/nginx/stream-access.log mysql_proxy; open_log_file_cache max1000 inactive20s;日志分析示例命令# 统计访问量TOP IP awk {print $1} stream-access.log | sort | uniq -c | sort -nr | head4.2 性能优化参数在events块中添加worker_connections 65536; stream { proxy_buffer_size 16k; tcp_nodelay on; }内核参数调优# 增加端口范围 echo net.ipv4.ip_local_port_range 1024 65000 /etc/sysctl.conf # 提高连接跟踪表大小 echo net.netfilter.nf_conntrack_max 131072 /etc/sysctl.conf sysctl -p4.3 安全加固措施限制访问IPallow 192.168.1.0/24; deny all;启用SSL加密需stream_ssl_moduleserver { listen 3306 ssl; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; proxy_pass backend; }5. 真实场景故障排查手册案例一连接频繁断开现象客户端每隔几分钟就断开连接检查proxy_timeout值是否过小解决调整为适合业务的长连接超时案例二UDP服务响应异常现象DNS查询时而超时检查proxy_responses是否设置为1解决对于DNS通常需要设为1案例三高并发时性能下降现象连接数上升后吞吐量下降检查worker_connections限制解决调整worker进程数和连接数上限在最近的一次电商大促中我们利用Nginx stream模块实现了Redis集群的透明代理。原本需要客户端感知的多节点配置现在只需连接统一的代理端口。当某个Redis节点故障时Nginx会自动剔除不可用节点业务端完全无感知。这种架构不仅简化了客户端配置还实现了秒级的故障转移。

更多文章