需监控网关层proxy_next_upstream触发的二次重试频率,核心是通过$upstream_addr与$upstream_status组合识别多次上游尝试,并利用$upstream_tries(≥1.19)或$request_id聚合日志来统计二次响应码分布及重试成功率。

要监控网关层因触发 proxy_next_upstream 而产生的二次(或多次)状态码重试频率,核心不是看客户端收到什么状态码,而是捕获 Nginx 在重试过程中实际打到不同后端节点时的真实响应结果。这需要日志中能区分「首次请求」和「重试请求」,并关联同一请求链路下的多次 upstream 尝试。
关键在于:Nginx 本身不直接记录“这是第几次重试”,但可通过组合变量+合理日志格式+后端配合,反推重试行为。
用 $upstream_addr 和 $upstream_status 捕捉每次尝试的真实结果
Nginx 的 $upstream_addr 会记录本次实际通信的后端地址(含端口),$upstream_status 记录该次通信返回的状态码(如 502、200 或 -)。两者结合,就能还原一次请求过程中所有被试过的节点及其响应。
你需要定义一个能同时记录多个 upstream 尝试的日志格式:
log_format retry_log '$remote_addr [$time_local] "$request" ' 'req_id="$http_x_request_id" ' 'upstream_list="$upstream_addr" ' 'upstream_statuses="$upstream_status" ' 'upstream_times="$upstream_response_time" ' 'tries="$upstream_tries" ' 'rt=$request_time';
⚠️ 注意:$upstream_tries 是 Nginx 1.19.0+ 新增变量,表示本次请求总共经历了几次 upstream 尝试(含首次),它是最直接的重试次数信号。若版本低于此,请用其他方式间接判断(见下文)。
在 location 中启用该日志:
access_log /var/log/nginx/retry.log retry_log;
识别重试行为的三种典型日志模式
只要 upstream_addr 字段中出现多个 IP(用逗号分隔),或 $upstream_tries > 1,就说明发生了重试。常见模式如下:
✅ 单次成功(无重试)
upstream_addr="192.168.1.10:8080",upstream_status="200",upstream_tries="1"✅ 一次重试后成功
upstream_addr="192.168.1.10:8080, 192.168.1.11:8080",upstream_status="502, 200",upstream_tries="2"
CPA Update - Secure CLI Proxy API Maintenance下载安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
✅ 两次重试失败
upstream_addr="192.168.1.10:8080, 192.168.1.11:8080, 192.168.1.12:8080",upstream_status="504, 503, 502",upstream_tries="3"
你可据此统计:
- 每分钟重试率 =
tries > 1 的请求数 / 总请求数 - 二次响应码分布 = 提取
upstream_status中第二个值(即第一次重试返回的状态码),统计502/503/504出现频次
没有 $upstream_tries?用 $request_id + 时间窗口聚合也能还原
如果 Nginx 版本较老($upstream_tries,可通过以下方式补足:
- 要求后端在响应头中返回唯一
X-Request-ID(或由 Nginx 自动生成:proxy_set_header X-Request-ID $request_id;) - 在日志中记录
$http_x_request_id和$upstream_addr、$upstream_status - 用脚本(如 Python 或 awk)按
X-Request-ID分组,合并同一请求的所有日志行
→ 若一个 ID 对应多条日志,且upstream_addr不同,即为重试链路
例如,两条日志共用 req_id=abc123,分别打到 10.0.1.10(502)和 10.0.1.11(200),即可判定为一次有效重试。
聚焦监控目标:二次状态码重试频率
你想盯的不是“有没有重试”,而是:
-
哪些错误码最常触发第二次尝试? → 统计所有
upstream_status中第二项(即首次重试返回码)的分布(如502占比 73%,504占 22%) -
重试是否真有用? → 计算
upstream_status最后一项是200的比例(成功率) -
重试集中在哪些节点? → 看
upstream_addr中第二位总是10.0.1.11,说明它成了“兜底热点”,可能配置权重或健康度异常
建议用 Prometheus + Loki 或 ELK 实现:
- 抽取
upstream_status字段,切分逗号,取[1]作为 secondary_status - 按
secondary_status做直方图,设置告警:rate(nginx_secondary_5xx_total[5m]) > 0.05
避免误判:排除非 proxy_next_upstream 引起的多地址
注意:$upstream_addr 多地址也可能是以下情况,需过滤:
- 使用了
split_clients或hash $cookie_uid导致天然多 upstream; - 后端主动 302 跳转,Nginx 跟随跳转并记录多个地址(此时
upstream_status通常为302, 200,不属于重试); - 配置了
proxy_redirect或sub_filter,干扰日志解析。
✅ 安全做法:只统计 upstream_status 包含 502/503/504 且后续出现 200 或再次 5xx 的行 —— 这类才属于 proxy_next_upstream 主动切换。
不复杂但容易忽略。










