$upstream_addr能完整记录重试链路,因其以逗号分隔形式按顺序保存每次连接的后端ip:port及对应$upstream_status、$upstream_response_time,需配合proxy_next_upstream显式配置与日志格式化使用。

可以通过 Nginx 的 $upstream_addr 变量结合日志格式与 upstream 配置,清晰记录每次重试所连接的具体后端地址,从而完整追踪 proxy_next_upstream 触发的重试链路。
理解 $upstream_addr 的多值行为
$upstream_addr 在一次请求中可能包含多个地址,以逗号分隔,顺序对应实际连接过的 upstream 服务器(包括失败和最终成功的那次)。例如:
表示:先连 10.0.1.10(失败),再连 10.0.1.11(失败),最后 10.0.1.12 成功返回。该变量仅在请求结束时(log phase)才完全填充,因此必须在 log_format 中使用,不能用于 rewrite 或 if 判断。
配置日志格式以捕获完整重试路径
在 http 块中定义带 $upstream_addr 和相关辅助变量的日志格式:
安装并运行 Aperture(Lightning Labs 的 L402 闪电反向代理),用于创建 L402 付费墙、配置付费 API 端点、为其他代理托管付费内容或测试 L402 认证流程。
log_format upstream_trace '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' 'upstream: "$upstream_addr" ' 'upstream_status: "$upstream_status" ' 'upstream_response_time: "$upstream_response_time" ' 'upstream_http_x_request_id: "$upstream_http_x_request_id"';
关键点:
-
$upstream_status同样是多值,与$upstream_addr一一对应,如502,504,200 -
$upstream_response_time也是多值,单位为秒,含毫秒精度(如0.002, 0.015, 0.048) - 搭配
$upstream_http_*可透传后端响应头(如 trace ID),便于跨服务关联
确保 proxy_next_upstream 正确触发重试
重试行为依赖显式配置,缺省不重试。需在 location 或 upstream 块中设置:
proxy_next_upstream error timeout http_502 http_503 http_504; proxy_next_upstream_tries 3; proxy_next_upstream_timeout 10s;
说明:
-
error:连接上游失败(如 refused、reset) -
timeout:代理连接或读取超时 -
http_502/503/504:明确将这些状态码视作可重试错误 -
proxy_next_upstream_tries限制最大尝试次数(含首次),默认为 0(无限),建议设为小整数防雪崩
验证与排查技巧
启用后通过真实请求 + 日志观察即可验证重试路径:
- 临时在 upstream 中配一个不可达地址(如
server 127.0.0.9:8000),再配两个正常节点,发起请求,检查 access log 中是否出现三段地址与状态 - 若
$upstream_addr只有一个值,常见原因:未命中重试条件(如后端返回 200 即使内容异常)、proxy_next_upstream未启用对应错误类型、或 upstream 中只剩一个可用节点 - 注意:健康检查(
health_check)会影响可用节点数,间接影响重试行为;开启keepalive不影响$upstream_addr记录逻辑










