通过分析$upstream_response_time的异常模式(如尾段突增、失败后成功、频繁“-”值),结合$upstream_addr绑定、p99分位统计及x-pod-phase日志标记,可精准识别并摘除已退场但仍承接流量的残余容器。
直接看 $upstream_response_time 的异常模式,就能判断退场容器是否还在承接流量并拖慢整体响应——它不依赖容器状态上报,而是从真实请求链路中“揪出”那些已标记下线却仍在被转发的残余节点。
盯住重试序列里的“尾段突增”和“失败后成功”
当一个容器正在滚动退出(如 Kubernetes 中 Terminating 状态),Nginx 仍可能因健康检查滞后或连接复用未及时断开,继续向其发请求。这类请求往往表现为:
-
$upstream_response_time出现多段值,且最后一段显著偏高(如"0.012, 0.015, 1.387") - 对应的
$upstream_status是"200, 200, 200"或"200, -, 200" -
$upstream_addr明确指向该退场 IP:Port(如10.1.2.101:8080)
这说明前两次请求快速返回(可能来自其他健康节点),但最后一次重试命中了即将关闭的容器,耗时陡增——不是后端真慢,而是它已无力响应。
识别“假健康”的单点毛刺
若某台容器已退场但未从 upstream 列表剔除,或 probe 检查间隔过长(如 30s),它可能长期处于“偶发响应、多数超时”状态。此时日志中会出现:
-
$upstream_response_time频繁出现"-",且与特定$upstream_addr强绑定(如10.1.2.101:8080, -总是成对出现) - 成功请求的耗时也明显高于集群均值(如 P95 达 800ms,其余节点仅 120ms)
-
$upstream_connect_time持续 > 50ms,表明建连阶段就卡顿,而非业务处理慢
这类节点虽未完全失联,但已丧失服务能力,属于典型的“残余损耗源”。
用 P99 分位+地址聚合定位低频但高损节点
平均值会掩盖退场容器的破坏性——它只承接少量请求,但每次都很慢。必须按 $upstream_addr 分组,计算各节点的 P99 $upstream_response_time:
- 对每个 upstream 地址,提取其所有非
-的耗时值,排序取第 99 百分位 - 若某地址的 P99 值是集群中位数的 3 倍以上,且该地址近期无新部署记录,大概率是退场残留
- 结合
$request_time对比:若$request_time ≈ $upstream_response_time,说明 Nginx 层无额外损耗,问题纯属该节点自身退化
配合主动探活与日志标记做闭环验证
光靠耗时不够,需交叉确认是否真在退场流程中:
- 在
proxy_set_header中透传容器元信息:proxy_set_header X-Node-Name $upstream_addr;proxy_set_header X-Pod-Phase "Terminating";(由 sidecar 或 annotation 注入) - 日志中若同时出现
X-Pod-Phase: Terminating和高$upstream_response_time,即可锁定残余损耗 - 发现后立即触发
nginx -s reload或调用上游服务的动态 upstream API 将其摘除
不复杂但容易忽略











