nginx的least_conn需叠加健康检查、状态采集与告警系统才能实现自动化容灾告警。1. 通过主动/被动健康检查确保least_conn只选真正健康的节点;2. 借助日志解析、openresty或stub_status采集连接状态;3. 基于关键指标对接prometheus等告警系统;4. 结合外部工具实现自动降级、扩容与流量切换。

Nginx 的 least_conn 本身不提供容灾告警能力,它只是一个请求分发策略,只负责选连接数最少的健康后端。要实现“自动化容灾告警对接”,必须在 least_conn 基础上,叠加健康检查、状态采集、外部监控与告警系统联动,形成闭环。
1. 先让 least_conn 真正感知故障节点
least_conn 不会自动剔除宕机或卡死的后端——它只看连接数,不管节点是否响应。所以第一步是强制它“只从真正健康的节点里挑”。
-
启用主动健康检查(推荐)
若使用 Nginx Plus(商业版),直接配置:upstream backend { least_conn; health_check interval=3 fails=2 passes=2 match=ok; server 192.168.1.10:8080; server 192.168.1.11:8080; } match ok { status 200; header Content-Type = "application/json"; body ~ '"status":"up"'; }这样:每 3 秒探活,连续 2 次失败就标记为
unavailable,least_conn自动跳过该节点。 -
开源版替代方案(被动 + 主动结合)
upstream backend { least_conn; server 192.168.1.10:8080 max_fails=2 fail_timeout=15s; server 192.168.1.11:8080 max_fails=2 fail_timeout=15s; } # 在 location 中开启失败重试与上游切换 proxy_next_upstream error timeout http_500 http_502 http_503 http_504; proxy_next_upstream_tries 3;
✅ 关键点:没有健康检查兜底,
least_conn就可能把请求持续打向已卡死但 TCP 连接未断的节点,造成“假空闲、真雪崩”。
2. 实时采集连接状态用于容灾判断
Nginx 自身不暴露各 upstream server 的实时连接数指标,需通过以下方式获取:
-
启用 stub_status + 自定义日志解析
在 server 块中加:location /nginx_status { stub_status; allow 127.0.0.1; deny all; }访问
http://localhost/nginx_status可看到类似:Active connections: 12 server accepts handled requests 12345 12345 23456 Reading: 0 Writing: 2 Waiting: 10
⚠️ 注意:这个页面不显示每个 server 的连接数,仅全局统计。
-
真正可用的方式:用
$upstream_addr和$upstream_bytes_received打点日志log_format upstream_log '$time_iso8601\t$upstream_addr\t$upstream_response_time\t$upstream_bytes_received'; access_log /var/log/nginx/upstream.log upstream_log;
配合定时脚本(如每 10 秒)统计各 IP 的活跃连接频次(近似反映负载倾向),异常下降(如某节点 1 分钟内无新连接)可触发初步告警。
更准的做法:用 OpenResty + shared dict 维护 per-server 连接计数器
在init_worker_by_lua_block中监听ngx.socket.connect/close,原子增减计数;再通过/api/upstream-stats接口对外暴露 JSON 数据,供 Prometheus 抓取。
3. 对接告警系统的关键指标与触发逻辑
| 指标 | 来源 | 容灾意义 | 告警建议 |
|---|---|---|---|
某 backend 连续 60 秒无新连接($upstream_addr 日志缺失) |
Nginx access log + 脚本聚合 | 可能被健康检查摘除,或网络隔离 | 触发「节点失联」告警,级别 P2 |
同一 upstream 中,某 server 的 max_conns 达到上限且持续 >30 秒 |
Nginx error log 或自研指标接口 | 节点实际已满载,least_conn 已自动绕过,但需扩容或排查慢请求 |
「连接池耗尽」告警,附 P99 响应时间趋势 |
stub_status 显示 Active connections 突增 300% 且 Waiting 占比 >80% |
stub_status 页面 + curl 定时采集 | Nginx 本身连接堆积,上游响应慢或后端全挂 | 「反向代理拥塞」告警,需紧急扩容或切流 |
| 主动健康检查失败率 >20%(过去 5 分钟) | Nginx Plus API /api/5/http/upstreams/.../health 或自建探针 |
节点真实不可用,least_conn 已失效 |
「集群可用性下降」告警,影响面评估 |
✅ 建议用 Prometheus + Grafana + Alertmanager 构建管道:
- 用
nginx-lua-prometheus或nginx-vts-exporter抓取指标- 写 PromQL 判断:
count by (upstream) (rate(nginx_upstream_requests_total{upstream=~"backend.*"}[5m]) == 0)- 告警规则推送到企业微信/钉钉/飞书,附跳转链接到 Nginx 日志查询页或 Kibana 面板
4. 容灾动作可自动化的典型场景
-
自动降级:当
backend中健康节点数 ≤ 1 时,Nginx 自动返回 503 或切到备用静态页(用error_page 503 /maintenance.html) - 自动扩容通知:Prometheus 告警触发 Webhook,调用云厂商 API(如阿里云 ECS StartInstance)或发工单
- 自动流量切换:配合 Consul 或 Nacos,将故障节点从服务注册中心下线,下游网关同步更新路由
⚠️ 注意:Nginx 本身不支持运行时修改 upstream 配置。若需动态剔除节点,要用
upstream_conf模块(Plus 功能)或通过外部程序 reload 配置(需平滑 reload,避免连接中断)。
不复杂但容易忽略。











