0

Nginx负载均衡健康检查配置详解:被动检测与主动检测的完整实战指南

2026.05.22 | youres | 11次围观

为什么负载均衡需要健康检查

负载均衡的核心任务是把请求分发到多台后端服务器,但如果某台服务器挂了,Nginx还往它发请求,用户就只能收到502错误。健康检查就是解决这个问题的——让Nginx自动识别故障节点,停止往它转发流量,等它恢复后再重新纳入集群。

Nginx的健康检查分两种:被动健康检查(开源版自带)和主动健康检查(需要第三方模块或商业版)。两种各有优缺点,下面逐个讲清楚。

一、被动健康检查:Nginx自带的max_fails和fail_timeout

被动检查的原理很简单:Nginx正常转发请求给后端服务器,如果后端返回错误或超时,Nginx就记录一次失败。失败次数达到阈值后,暂时不再往这台服务器发请求。

1.1 核心参数说明

在upstream块里给每个server配置两个参数:

  • max_fails:最大失败次数,默认值是1。超过这个次数,Nginx标记该服务器为不可用
  • fail_timeout:失败后暂停转发的时间窗口,默认10秒。在这个时间内不往故障节点发请求,过了之后会再尝试一次

1.2 配置示例

upstream backend {
    server 192.168.1.10:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.11:8080 max_fails=3 fail_timeout=30s;
    server 192.168.1.12:8080 backup;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
        proxy_next_upstream error timeout http_502 http_503 http_504;
    }
}

这个配置的意思是:每台服务器连续3次请求失败后,标记为不可用,30秒内不再转发请求给它。proxy_next_upstream指定遇到哪些错误时自动切换到下一台服务器。

1.3 被动检查的缺点

  • 只有真实用户请求到了故障节点才会触发检测,第一波用户还是会遇到错误
  • fail_timeout到期后只尝试一次,如果刚好又失败,又要等一个周期
  • 无法定期主动探测服务器状态,故障发现滞后
  • 没有健康状态的查看页面,运维不直观

二、主动健康检查:nginx_upstream_check_module

主动检查的思路是:Nginx按固定时间间隔主动向后端发探测请求,根据响应判断服务器是否健康。故障节点在用户请求到来之前就被摘除,真正实现零误差转发。

开源版Nginx没有内置主动检查模块,最常用的是淘宝团队开发的nginx_upstream_check_module。需要重新编译Nginx加入这个模块。

2.1 编译安装

# 安装依赖
yum install -y gcc gcc-c++ pcre-devel openssl-devel patch

# 下载Nginx源码和模块
wget http://nginx.org/download/nginx-1.24.0.tar.gz
wget https://github.com/yaoweibin/nginx_upstream_check_module/archive/master.zip

# 解压
tar xf nginx-1.24.0.tar.gz
unzip master.zip

# 打补丁(进入Nginx源码目录)
cd nginx-1.24.0
patch -p1 < ../nginx_upstream_check_module-master/check_1.20.1+.patch

# 编译安装
./configure --add-module=../nginx_upstream_check_module-master
make && make install

注意:补丁版本要跟Nginx版本匹配,check_1.20.1+.patch适用于Nginx 1.20.1及以上版本。

2.2 配置示例

upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;

    # 主动健康检查配置
    check interval=3000 rise=2 fall=3 timeout=1000 type=http;
    check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

server {
    listen 80;
    location / {
        proxy_pass http://backend;
    }

    # 健康状态查看页面
    location /status {
        check_status;
        access_log off;
        allow 192.168.1.0/24;
        deny all;
    }
}

2.3 参数详解

  • interval:检测间隔,单位毫秒。3000表示每3秒检测一次
  • rise:连续成功次数。rise=2表示连续2次检测成功后标记为健康,恢复转发
  • fall:连续失败次数。fall=3表示连续3次检测失败后标记为故障,停止转发
  • timeout:每次检测的超时时间,单位毫秒
  • type:检测类型,支持tcp、http、ssl、ajp等
  • check_http_send:HTTP检测时发送的请求内容
  • check_http_expect_alive:认为健康的HTTP状态码

2.4 健康状态页面

配置了check_status后,访问/status路径可以看到每台后端服务器的健康状态,包括:

  • 服务器地址和端口
  • 当前状态(up/down)
  • 最近一次检测时间和结果
  • 连续成功/失败次数

这个页面是运维排查问题的重要入口,建议只允许内网访问。

三、Nginx Plus商业版的健康检查

如果用的是Nginx Plus(商业版),内置了health_check指令,不需要额外编译模块:

upstream backend {
    server 192.168.1.10:8080;
    server 192.168.1.11:8080;
}

server {
    location / {
        proxy_pass http://backend;
        health_check interval=5s fails=3 passes=2 uri=/health;
    }
}

商业版的优势是配置简洁、官方维护、支持更丰富的检测条件(比如匹配响应体内容)。但需要付费,适合企业生产环境。

四、两种方案对比

特性被动检查(max_fails)主动检查(check模块)
是否需要编译不需要需要重新编译
故障发现速度慢,依赖真实请求快,定期主动探测
状态查看页面没有有(check_status)
适用场景小规模、对延迟不敏感生产环境、对可用性要求高
维护成本中等(需维护编译版本)

五、实战建议

  • 小型站点或测试环境,用被动检查就够了,配置简单零依赖
  • 生产环境一定要用主动检查,故障节点零延迟摘除,用户体验好
  • 健康检查的间隔别太短(1秒以下),否则后端压力大;也别太长(超过10秒),发现故障慢
  • rise设2比设1更稳,避免偶发超时误判;fall设3同理
  • 后端应用一定要提供/health接口,返回200就表示健康,别用HEAD请求去检测复杂业务路径
  • check_status页面务必限制内网访问,别暴露给公网
  • 如果不想重新编译Nginx,可以考虑用Nginx Plus或外部监控工具(如Consul+健康检查脚本)配合实现

六、常见问题

Q:max_fails=0是什么意思?

表示不统计失败次数,即永远不标记服务器为不可用。一般不建议这样设置,除非你有外部监控系统单独处理故障切换。

Q:主动检查模块打补丁失败了怎么办?

补丁版本必须跟Nginx版本对应。先确认Nginx版本,然后到模块的GitHub页面查看支持的补丁文件列表。版本不匹配就换个补丁或换个Nginx版本。

Q:配置了check后Nginx启动报错?

最常见的错误是check指令写在server块而不是upstream块里。check相关指令的位置:check写在upstream块,check_status写在server块的location里。

Q:后端服务器恢复了但流量还是没回来?

检查rise参数是否设置过大。rise=2需要连续2次检测成功才恢复,如果检测间隔是3秒,恢复需要6秒。可以适当减小rise或缩短interval。

相关文章

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论
881文章数 0评论数
作者其它文章