小易说IT 小易说IT

Nginx stream + ngx_stream_upstream_check_module 主动健康检查

模块说明:ngx_stream_upstream_check_module 是淘宝开源 Nginx 补丁模块,需要给 Nginx 打补丁重新编译,原生 Nginx 不自带。 能力:主动周期性探测后端 TCP 服务,支持 TCP 握手探测、MySQL ping 探测、Redis ping 探测等;节点异常自动摘除,恢复后自动加回,弥补原生 stream 只有被动健康检查的短板。 探测模式:mysql 模式,会发送 MySQL 协议 ping 包,不只是简单 TCP 端口连通性校验,能判断 MySQL 实例是否存活。

⚠️ 编译前置步骤(必须先做)

  1. 下载对应版本 Nginx 源码

  2. 下载 ngx_stream_upstream_check_module 源码

  3. 进入 nginx 源码目录打补丁:

patch -p1 < ../ngx_stream_upstream_check_module/stream-check.patch
  1. 编译参数必须带上 --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

生产重要坑点

  1. 模块版本兼容性ngx_stream_upstream_check_module 旧版本对新版 Nginx(1.21+)兼容性差,容易打补丁失败。很多企业现在转向 HAProxy 做 MySQL 四层 LB,原生自带 MySQL 探测,不用编译补丁。

  2. MySQL 账号权限 如果配置 check_user / check_password,监控账号只需要最基础权限,不需要业务权限:

    CREATE USER 'monitor'@'nginx-lb-ip' IDENTIFIED BY 'Monitor@123456';
    

    部分新版模块,mysql ping 探测不需要账号,只需要建立 MySQL 连接即可。

  3. 探测连接占用 每个后端节点会持续产生探测连接,间隔 2s,注意 MySQL 的max_connections,大量后端节点会产生不少探测连接。

  4. 区分读写场景 这个 LB 配置只适合 MySQL 读节点集群(从库 / MGR 只读节点);MySQL 写节点一般单点,不放入 upstream。

  5. 防火墙 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,转载请注明出处。

原文链接 https://www.yijunzhao.cc/archives/nginx-stream-upstream-check-module-active-health-check

欢迎访问 https://www.yijunzhao.cc/

https://www.yijunzhao.cc/