模块说明:
ngx_stream_upstream_check_module是淘宝开源 Nginx 补丁模块,需要给 Nginx 打补丁重新编译,原生 Nginx 不自带。 能力:主动周期性探测后端 TCP 服务,支持 TCP 握手探测、MySQL ping 探测、Redis ping 探测等;节点异常自动摘除,恢复后自动加回,弥补原生 stream 只有被动健康检查的短板。 探测模式:mysql模式,会发送 MySQL 协议 ping 包,不只是简单 TCP 端口连通性校验,能判断 MySQL 实例是否存活。
⚠️ 编译前置步骤(必须先做)
下载对应版本 Nginx 源码
下载
ngx_stream_upstream_check_module源码进入 nginx 源码目录打补丁:
patch -p1 < ../ngx_stream_upstream_check_module/stream-check.patch
编译参数必须带上
--with-stream和模块:
./configure --with-stream --add-module=../ngx_stream_upstream_check_module
make && make install
校验模块是否编译成功:
nginx -V,看编译参数包含ngx_stream_upstream_check_module
完整 nginx.conf 配置示例
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
events {
worker_connections 1024;
}
stream {
upstream mysql_read_cluster {
least_conn;
server 10.0.1.10:3306 weight=5;
server 10.0.1.11:3306 weight=3;
server 10.0.1.12:3306 weight=2;
server 10.0.1.13:3306 backup;
# ========== 主动健康检查核心配置 ==========
check mysql; # 探测类型:mysql,自动发送MySQL ping包
check_interval 2000; # 探测间隔:2000ms = 2秒探测一次
check_fails 3; # 连续3次探测失败 → 标记节点down,摘除
check_success 2; # 连续2次探测成功 → 标记节点up,恢复上线
check_timeout 1000; # 单次探测超时时间:1000ms
check_send_timeout 1000;
check_read_timeout 1000;
# 可选:MySQL账号密码,部分版本模块需要认证才能执行ping
# check_keepalive_time 10000;
# check_user "monitor";
# check_password "Monitor@123456";
}
# 健康检查状态页面(TCP状态页,可浏览器访问看节点状态)
server {
listen 8080;
check_status;
access_log off;
}
log_format proxy_stream '$remote_addr [$time_local] '
'$protocol $status $bytes_sent $bytes_received '
'$session_time "$upstream_addr" '
'"$upstream_bytes_sent" "$upstream_bytes_received" "$upstream_connect_time"';
access_log /var/log/nginx/stream-access.log proxy_stream;
# MySQL四层代理入口
server {
listen 3306;
proxy_pass mysql_read_cluster;
proxy_connect_timeout 10s;
proxy_timeout 600s;
proxy_buffer_size 16k;
}
}
# http块保留,用于web业务,和stream互不干扰
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
}
核心参数详解
check mysql;
check mysql:使用 MySQL 协议探测,不是单纯 TCP 握手。会建立连接,发送 MySQL ping 命令。如果改为
check tcp;:仅 TCP 端口连通性探测,只看端口是否通,无法判断 MySQL 实例卡死、只读、复制异常。
check_interval 2000;
check_fails 3;
check_success 2;
check_timeout 1000;
check_interval:每隔多少毫秒探测后端节点check_fails:连续失败多少次,判定节点不可用,从负载均衡摘除check_success:连续成功多少次,判定节点恢复,重新加入集群check_timeout:单次探测请求超时时间
check_status;:开启状态页面,访问http://LB_IP:8080,可以看到所有后端节点状态:up / down,探测次数,失败统计。 页面示例:Nginx Stream upstream check status upstream mysql_read_cluster server 10.0.1.10:3306 status up server 10.0.1.11:3306 status down
验证命令
# 检查配置语法
nginx -t
# 平滑重载
nginx -s reload
# 访问健康检查页面
curl http://127.0.0.1:8080
生产重要坑点
模块版本兼容性
ngx_stream_upstream_check_module旧版本对新版 Nginx(1.21+)兼容性差,容易打补丁失败。很多企业现在转向 HAProxy 做 MySQL 四层 LB,原生自带 MySQL 探测,不用编译补丁。MySQL 账号权限 如果配置
check_user/check_password,监控账号只需要最基础权限,不需要业务权限:CREATE USER 'monitor'@'nginx-lb-ip' IDENTIFIED BY 'Monitor@123456';部分新版模块,mysql ping 探测不需要账号,只需要建立 MySQL 连接即可。
探测连接占用 每个后端节点会持续产生探测连接,间隔 2s,注意 MySQL 的
max_connections,大量后端节点会产生不少探测连接。区分读写场景 这个 LB 配置只适合 MySQL 读节点集群(从库 / MGR 只读节点);MySQL 写节点一般单点,不放入 upstream。
防火墙 Nginx 服务器需要能访问后端 MySQL 3306 端口;健康检查页面 8080 端口按需限制访问源 IP,不要公网暴露。
备选:HAProxy 简单对比(选型参考)
Nginx+stream-check:需要源码打补丁编译,维护成本高;
HAProxy:原生支持
mysql-check,开箱即用,四层 LB+MySQL 协议探测,很多数据库集群首选。
如果你需要,我可以顺便给一份 HAProxy MySQL 集群负载均衡 + mysql-check 健康检查配置,作为替代方案。
扩展:Redis 探测写法(同模块,追加到 stream 块)
upstream redis_cluster {
least_conn;
server 10.0.1.20:6379;
server 10.0.1.21:6379;
check redis;
check_interval 2000;
check_fails 3;
check_success 2;
check_timeout 1000;
}
server {
listen 6379;
proxy_pass redis_cluster;
proxy_connect_timeout 5s;
proxy_timeout 300s;
}本文原创作者:易君召,详见:https://www.yijunzhao.cc/about,转载请注明出处。
原文链接
欢迎访问