监控Nginx故障转移耗时,核心是测“用户请求从失败到成功的时间”,需关联$upstream_response_time、$upstream_addr+$upstream_status、$request_time+$status三类字段,结合主动健康检查与日志语义化分析全链路延迟。

要监控后端服务宕机时 Nginx 故障转移的耗时,核心不是测“Nginx 多快切走”,而是测“用户请求多长时间才从失败变成功”——这需要把故障触发、重试行为、节点状态变更、响应结果全部串起来看。
关键指标必须包含三类数据
单靠一个数字无法反映真实体验。需同步采集并关联以下三组字段:
- $upstream_response_time:每次尝试的真实后端耗时(含重试逗号分隔值),用于识别哪次重试成功、哪次超时
-
$upstream_addr + $upstream_status:记录每次尝试的目标地址和返回状态(如
10.20.30.41:8080, 10.20.30.42:8080对应504, 200),确认是否发生了跨节点切换 - $request_time + $status:客户端视角的总耗时与最终结果,比如一次请求耗时 1.2s、返回 200,说明故障转移完成且用户无感;若耗时 1.2s 但返回 504,则说明重试失败或未启用 backup
日志格式要支持重试链路还原
默认日志无法区分重试次数和对应结果。需定义带语义的专用格式:
log_format failover_log '$remote_addr [$time_local] "$request" '
'$status $body_bytes_sent '
'"$upstream_addr" "$upstream_response_time" "$upstream_status" '
'$request_time $msec';启用后,一行日志就能看出完整重试路径,例如:
→ 表示第一次连 41 节点超时(504),0.842s 后换 42 节点成功(200),总耗时 0.879s,真正故障转移延迟 ≈ 0.037s(第二次响应耗时)+ 网络切换开销。
Grafana 中计算“有效转移耗时”的方法
不能直接对 $request_time 取平均——它混入了正常请求。应在 Prometheus 或 Loki 中做条件聚合:
- 筛选出发生过失败再成功的请求:
count by (uri) (rate(nginx_upstream_status{code=~"50[24]"}[5m])) > 0 and count by (uri) (rate(nginx_upstream_status{code="200"}[5m])) > 0 - 提取首次失败到最终成功的耗时差:用
quantile_over_time(0.95, (timestamp(request_time) - timestamp(upstream_response_time[0]))[1h:])(Loki + Grafana)或 PromQL 中结合 histogram_quantile 与 label_match 过滤重试标记 - 在面板中叠加两个曲线:一条是
P95 $request_time for requests with upstream_status contains "504",另一条是P95 $request_time for requests where final $status == 200 after retry,差值即为典型故障转移感知延迟
配合 upstream 主动健康检查验证转移时效
被动检查(靠请求失败触发)有滞后性,会拉长用户侧故障时间。建议启用主动探测模块(如 nginx_upstream_check_module):
- 配置
check interval=2 rise=1 fall=2,确保节点宕机后 2–4 秒内被标记为 down - 在 Grafana 中新增面板,展示
nginx_upstream_check_fails_total和nginx_upstream_check_down_start_timestamp,对比该时间戳与第一条 504 日志的时间差,即可评估 Nginx “发现故障”的速度 - 再对比第一条 200(来自 backup 或其他 healthy 节点)的时间,得出“发现 + 切流 + 成功”的全链路耗时


















