Nginx开源版可通过upstream+max_fails实现被动健康检查,外部脚本控制本地/health端点或标记文件,结合proxy_next_upstream触发故障转移;Plus版支持health_check指令与API动态管理后端状态。

Nginx 本身不直接执行外部健康检查脚本,但可以通过 主动健康检查 + 自定义状态页 + 外部脚本联动 的方式,实现故障转移与外部健康检查的协同。核心思路是:让外部脚本控制一个“健康标记文件”或 HTTP 状态页,Nginx 通过 proxy_next_upstream 和 health_check(需 Plus 版)或基于 upstream_hash/max_fails/fail_timeout 的被动机制配合该标记,动态调整后端可用性。
用 upstream + max_fails 实现基础故障转移(开源版通用)
这是最常用、无需 Nginx Plus 的方案。Nginx 依赖连接失败和响应超时等被动信号判断后端是否宕机,外部脚本则负责“提前干预”——例如在应用未完全崩溃但已不可用时,主动让其被标记为不可用。
- 在 upstream 中为每个 server 设置
max_fails=1 fail_timeout=10s,让 Nginx 快速剔除异常节点 - 外部脚本(如每 5 秒运行一次)检查服务逻辑健康(如 DB 连通性、API 响应内容),若失败,就向该机器的本地 HTTP 端点(如
http://127.0.0.1:8080/health)返回 5xx 或直接关闭该端口 - Nginx 配置中将该本地端点作为 health check 探针目标(用
proxy_pass转发到它),再结合proxy_next_upstream error timeout http_500,让请求在探针失败时自动转发到其他 upstream server
用 stub_status + 外部脚本轮询模拟主动检查(轻量级联动)
如果你已有 Nginx 开启了 stub_status,可复用它作为健康信号出口。外部脚本定期调用 /nginx_status,解析 Active/Reading 等指标;若发现异常(如 Active 连接突增、Requests 停滞),就触发本机服务下线动作(如修改本地标记文件)。
- 在 upstream server 上部署一个简单 Web 服务(如 Python Flask),监听
/readyz,读取本地文件/tmp/nginx-ready内容:存在且内容为ok则返回 200,否则返回 503 - 外部健康检查脚本根据业务逻辑决定是否写入/删除该文件
- Nginx upstream 配置中,把该
/readyz接口作为健康探测路径(配合proxy_next_upstream和自定义 error_page 捕获 503)
使用 Nginx Plus 的 health_check 指令(企业级推荐)
若使用 Nginx Plus,可直接利用其原生主动健康检查能力,并通过 API 动态管理 upstream 成员状态,与外部脚本深度联动。
- 配置
health_check interval=5 fails=2 passes=2 uri="/health" match=healthy;,其中match可定义响应体关键字或状态码规则 - 外部脚本不直接操作 Nginx,而是调用 Nginx Plus 的
upstream_confAPI(如POST /api/6/http/upstreams/backend/servers/1/down)强制下线节点 - 脚本也可定时拉取
/api/6/http/upstreams/backend/servers获取当前状态,做闭环校验
关键注意事项与建议
无论采用哪种方式,都需注意几个易忽略但影响稳定性的细节:
- 外部脚本必须具备幂等性,避免重复执行导致误下线;建议加锁(如 flock)或使用原子文件写入
- Nginx 的
fail_timeout应略大于脚本检查周期,防止抖动频繁切换;例如脚本每 3 秒检查一次,fail_timeout设为 5–10 秒较稳妥 - 不要仅依赖 HTTP 状态码 503 来判断故障——有些业务接口本身就返回 503 表示限流,应结合响应体内容或 header 字段做更精准匹配
- 所有健康检查路径(如
/health)务必限制访问来源(allow 127.0.0.1; deny all;),防止被恶意探测或触发











