应通过定制Nginx access log记录$upstream_next_count变量,再经Filebeat/Loki或Fluentd等日志解析链路提取为Prometheus指标;该变量自1.23.0起精确反映proxy_next_upstream触发的重试次数,并需结合upstream_status和upstream_addr过滤伪重试场景。

要监控 Nginx 反向代理转发失败后的重试次数,不能只依赖 Prometheus 原生 nginx-exporter 的默认指标——它不直接暴露 proxy_next_upstream 触发的重试行为。真正可行的方式是:**通过定制 access log 记录重试标识,再由日志采集链路(如 Filebeat + Loki / Fluentd + Prometheus Exporter)解析并暴露为 Prometheus 指标**。
用 $upstream_next_count 打点重试动作
Nginx 自 1.23.0 起稳定支持内置变量 $upstream_next_count,它精准反映因 proxy_next_upstream 切换上游节点的次数:
- 值为 0 → 首次请求,未重试
- 值为 1 → 触发一次重试(共发送 2 次)
- 值为 2 → 触发两次重试(共发送 3 次)
在 log_format 中显式记录该变量:
access_log /var/log/nginx/retry.log retry_log;
用日志解析器转成 Prometheus 指标
原生 nginx-exporter 不解析日志字段,需借助外部工具将 next_count 提取为可聚合指标:
- 用 prometheus-logstash-exporter 或 mtail 解析日志行,按
next_count > 0统计重试请求数 - 用 Fluentd + prometheus-plugin 提取
next_count字段,生成指标如nginx_upstream_retry_count{next_count="1"} - 若已用 Loki + Promtail,可通过 LogQL 定义指标:
sum by (next_count) (count_over_time({job="nginx"} |~ "next_count=[1-9]" [1h]))
关联 upstream_status 和重试原因
单看重试次数不够,还要知道为什么重试。Nginx 同时提供 $upstream_status(逗号分隔的各次响应码)和 $upstream_tries(总尝试次数):
- 日志中出现
upstream_status="504,502"且next_count=1→ 第一次重试因超时失败,第二次因服务不可用失败 - 配置
proxy_next_upstream error timeout http_500后,upstream_status中含500才算有效重试触发 - Prometheus 查询可写成:
rate(nginx_upstream_retry_total{next_count=~"1|2|3"}[5m]),再用upstream_status标签做多维下钻
避免误统计:过滤伪重试场景
不是所有 next_count > 0 都代表容错重试成功切换,需排除干扰:
-
upstream_addr显示相同 IP:port 多次 → 实为长连接复用,非重试 -
next_count=0但upstream_response_time > 3s→ 单次慢响应,未触发重试 -
upstream_addr切换但next_count=0→ 属于负载均衡调度(如 ip_hash),不是proxy_next_upstream行为


















