如何在 Nginx 中配置 health_check 主动健康检查模块

文章导读
先说结论:Nginx 开源版原生不支持 active health_check 指令,该功能仅存在于 Nginx Plus 商业版。开源版需通过被动参数或编译第三方模块实现类似效果。
📋 目录
  1. 方案一:Nginx Plus 原生主动检查
  2. 方案二:开源版被动检查(内置)
  3. 方案三:开源版编译第三方模块(主动检查)
  4. 验证与排查步骤
  5. 常见坑
A A

先说结论:Nginx 开源版原生不支持 active health_check 指令,该功能仅存在于 Nginx Plus 商业版。开源版需通过被动参数或编译第三方模块实现类似效果。

  • 核心区别:Plus 版支持主动探测,开源版默认仅支持被动失败计数
  • 关键风险:开源版多 Worker 架构下,被动失败计数默认不共享,可能导致故障切换不一致
  • 第三方方案:编译 nginx_upstream_check_module 可实现主动检查,但需注意版本兼容性及维护状态
  • 验收:查看 error.log 是否有 unknown directive 报错,或通过状态接口验证节点状态

方案一:Nginx Plus 原生主动检查

如果你拥有 Nginx Plus 授权,这是最稳定的方案。主动检查会独立于业务流量发送探测请求。

配置示例

http 块定义共享内存 zone,在 upstream 块启用 health_check

如何在 Nginx 中配置 health_check 主动健康检查模块
http {
    upstream backend {
        zone server_zones 64k;
        server backend1.example.com;
        server backend2.example.com;
        health_check interval=10s fails=3 passes=2;
    }
}

验证方法

  • 查看状态:Nginx Plus 提供状态 API,可查询 upstream 节点健康状态。
  • 观察日志:正常工作时 error.log 不应有频繁的上游连接错误。
  • 故障测试:手动停止一台后端,观察 Plus 状态接口是否迅速标记该节点为 unhealthy。

注意事项

主动检查会持续发送请求,interval 设置过小会增加后端 QPS 压力,生产环境建议根据后端承载能力调整间隔。

方案二:开源版被动检查(内置)

开源版默认采用被动检查,只有当业务请求转发失败时才会触发计数。

配置示例

使用 max_failsfail_timeout 控制失败阈值:

如何在 Nginx 中配置 health_check 主动健康检查模块
upstream backend {
    server backend1.example.com max_fails=3 fail_timeout=30s;
    server backend2.example.com max_fails=3 fail_timeout=30s;
}

技术局限(重要)

开源版被动检查状态默认在每个 Worker 进程内独立维护,多 Worker 环境下可能不一致。 这意味着一个 Worker 认为节点故障,另一个 Worker 可能仍会转发请求过去,导致部分用户访问失败。

验证方法

  • 日志排查:重启后检查 error.log,确认没有 unknown directive 报错。
  • 故障测试:手动停掉一台后端,观察日志中 upstream 连接错误计数是否达到 max_fails 阈值。
  • 流量观察:在有持续流量的情况下,故障节点会被暂时剔除;无流量时无法触发检测。

方案三:开源版编译第三方模块(主动检查)

如果必须在开源版实现主动检查,可使用第三方补丁模块(如 nginx_upstream_check_module)。注意:该模块可能不再维护,需寻找兼容当前 Nginx 版本的补丁,直接编译易失败。

如何在 Nginx 中配置 health_check 主动健康检查模块

编译步骤

  1. 下载对应 Nginx 版本的源码。
  2. 下载第三方模块源码(例如 GitHub 上的 nginx_upstream_check_module 分支)。
  3. 编译时添加模块参数:
./configure `--add-module`=/path/to/nginx_upstream_check_module
make
make install

配置示例

第三方模块通常使用 check 指令,参数包含 interval, rise, fall 等:

upstream backend {
    server backend1.example.com:8080;
    server backend2.example.com:8080;
    check interval=3000 rise=2 fall=5 timeout=1000 type=http;
    check_http_send "HEAD / HTTP/1.0\r\n\r\n";
    check_http_expect_alive http_2xx http_3xx;
}

风险提示

  • 版本兼容:模块代码可能依赖旧版 Nginx 内部结构,升级 Nginx 核心时需重新验证模块兼容性。
  • 维护成本:第三方模块社区支持有限,出现 Bug 需自行排查源码。
  • 状态同步:部分第三方模块不支持多 Worker 状态共享,需确认文档说明。

验证与排查步骤

无论采用哪种方案,部署后建议执行以下验证:

  1. 配置语法检查:运行 nginx -t 确保配置无误。
  2. 日志监控:重启后检查 error.log,若有 unknown directive "health_check" 说明版本不对或模块未加载。
  3. 故障切换测试:手动停掉一台后端服务,观察请求是否自动切换到其他节点,记录切换耗时。
  4. 压力评估:开启主动检查后,监控后端服务 QPS 变化,避免检查频率过高拖垮后端。

常见坑

  • 指令混淆:把 Tengine 的配置语法直接用到官方开源 Nginx 上,Tengine 自带健康检查模块,但官方 Nginx 没有。
  • 多 Worker 状态不一致:开源版被动检查状态下,不同 Worker 进程对后端健康状态的判断可能不同,建议配合 keepalive 或减少 Worker 数测试。
  • 资源消耗:主动检查会持续发送请求,后端服务压力大时要调整检查间隔(interval),避免雪崩。
  • 模块失效:第三方模块编译后,若升级 Nginx 版本未重新编译模块,会导致健康检查功能失效。