nginx需通过主动探测、语义判断、状态暴露、动态调度四环节实现真实健康感知:启用nginx_upstream_check_module,发/health请求并校验响应内容,暴露prometheus指标并告警,基于健康分动态路由与优雅上下线。

要让 Nginx 真正感知后端集群是否可用,不能只靠“连得上”,得让它能主动问、懂语义、看得见、动得了——四个环节缺一不可。
用主动探测代替被动等待
原生 Nginx 的 max_fails + fail_timeout 是被动机制:必须等真实请求失败才反应,容易打到未就绪或假死节点。真正可靠的感知,得靠主动定时探活:
- 启用 nginx_upstream_check_module(OpenResty 默认含,开源 Nginx 需编译添加)
- 在 upstream 中加 check 指令:
check interval=3 rise=2 fall=3 timeout=1 type=http - 发真实请求:
check_http_send "GET /health HTTP/1.1\r\nHost: api.example.com\r\nConnection: close\r\n\r\n" - 严格判断健康:
check_http_expect_alive http_2xx,拒绝把返回 503 或{"status":"DOWN"}的节点当可用 - 务必设 default_down=true,防止 Nginx 启动时把还没 ready 的节点误标为 up
让探测结果反映真实业务状态
只看 HTTP 状态码 200 不够,有些服务 /health 接口永远返回 200,但数据库已断、线程池打满。关键是要结合响应内容和上下文:
- 后端应提供专用就绪接口(如
/actuator/ready或/healthz),不走主业务链路 - 若用 OpenResty,可在
log_by_lua_block中解析 JSON 响应,提取status、load、dbStatus字段做二次判定 - 对高敏感服务,可搭配 TCP 层探测(
type=tcp)作为兜底,绕过应用层干扰 - 避免用
HEAD请求——部分框架不支持或响应不完整,优先用GET并带 Host 头
暴露状态页并接入监控闭环
感知不到等于没感知。所有检查结果必须可查、可采、可告警:
- 配置
location /status { check_status; allow 10.0.0.0/8; deny all; },返回结构化节点列表(IP、up/down、fail count、last response time) - 用 nginx-module-vts 或自定义 Lua exporter 暴露 Prometheus 可抓取的指标,如
upstream_down{server="10.1.2.3:8080"} - 设置告警规则:连续 2 分钟
upstream_down == 1触发企业微信/钉钉通知 - 状态页禁止公网访问,只允运维内网或跳板机 IP 访问,防止拓扑泄露
基于状态动态调整流量分发
健康感知的终点不是日志里多一行 “down”,而是路由行为实时变化:
- 在
balancer_by_lua_block中读取共享字典里的节点健康分(例如 0–100 分),自动跳过低于阈值的节点 - 探测到节点 down 时,调用 webhook 发送事件,触发 CMDB 自动标注、SLA 统计暂停
- 配合
slow_start=30实现优雅上线:新节点恢复后,权重从 0 缓慢提升,避免瞬间压垮 - 人工摘除前,先设
weight=0,再观察 access_log 中该节点$upstream_status是否归零,确认无流量再下线











