Nginx的ngx_http_proxy_module不定义独立变量,而是透传并依赖标准代理相关变量(如$proxy_host、$upstream_status等),用于proxy_set_header、日志、条件判断等场景,实现动态代理控制与可观测性。

nginx 的 ngx_http_proxy_module 模块本身并不定义独立的“变量”,它依赖并透传上游响应、客户端请求、代理连接等上下文中的标准变量(如 $proxy_host、$proxy_port、$proxy_add_x_forwarded_for 等),这些变量主要用于 proxy_set_header、proxy_pass、日志记录等指令中,实现动态代理行为控制。
常用 proxy 相关变量及其典型用途
以下变量虽非由 ngx_http_proxy_module “创建”,但由其语义触发或在代理场景中高频使用:
-
$proxy_host:当前proxy_pass指令中指定的后端主机名(不含端口)。可用于构造原始请求头,例如:proxy_set_header Host $proxy_host; -
$proxy_port:当前proxy_pass中指定的后端端口。配合$proxy_host可还原完整 upstream 地址。 -
$proxy_add_x_forwarded_for:在原有X-Forwarded-For值后追加客户端真实 IP($remote_addr),若原头不存在则直接设为$remote_addr。这是反向代理中传递客户端 IP 的标准做法。 -
$proxy_protocol_addr和$proxy_protocol_port:仅当启用 PROXY 协议(proxy_protocol on;)时有效,表示客户端通过 PROXY 协议声明的真实地址和端口,比$remote_addr更可信(适用于 TCP 层透传场景)。 -
$upstream_addr:实际与之通信的 upstream server 地址(含 IP:port 或 unix socket 路径),支持负载均衡场景,常用于日志记录或调试。 -
$upstream_status:上游服务器返回的 HTTP 状态码(如 200、502、504),可用于条件日志或监控。 -
$upstream_http_*(如$upstream_http_x_rate_limit_remaining):获取上游响应头中指定字段的值,需注意名称转为小写并用下划线替代连字符(X-Rate-Limit-Remaining → $upstream_http_x_rate_limit_remaining)。
变量在 proxy_set_header 中的关键用法
该指令是变量最核心的应用场景,用于动态构造发往后端的请求头:
- 确保后端能识别原始请求来源:
proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - 传递原始 Host 和协议信息,避免后端 URL 构造错误:
proxy_set_header Host $host;(用客户端 Host)proxy_set_header X-Forwarded-Proto $scheme; - 转发自定义头或内部标识:
proxy_set_header X-Request-ID $request_id;(需配合random_index或map模块生成)
变量在日志与条件判断中的实用技巧
借助 log_format 和 map 指令,可将 proxy 变量转化为可观测性与路由逻辑的关键依据:
- 在 access_log 中记录代理链路详情:
log_format proxy_log '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$upstream_addr" "$upstream_status" "$upstream_http_x_cache";' - 基于上游状态做差异化响应(需配合 error_page 或 if):
map $upstream_status $cache_bypass { 502 1; 504 1; default 0; }proxy_cache_bypass $cache_bypass; - 根据上游响应头决定是否缓存:
proxy_cache_valid 200 302 10m;proxy_ignore_headers Cache-Control;
再结合$upstream_http_cache_control做更细粒度控制(需自定义逻辑)
注意事项与常见误区
这些变量的行为受上下文严格约束,误用易导致静默失败:
-
$proxy_host和$proxy_port仅在proxy_pass使用域名或带端口的地址时才生效;若写成proxy_pass http://127.0.0.1:8080;,它们值为空字符串。 -
$upstream_http_*类变量仅在 upstream 返回响应后才可读取,不能用于proxy_set_header(因为那是请求阶段),只能用于日志、响应头修改(add_header)或后续处理。 -
$proxy_add_x_forwarded_for不会覆盖已有值,而是追加,因此若客户端已伪造该头,可能造成污染;生产环境建议先清空:proxy_set_header X-Forwarded-For "";再设为$proxy_add_x_forwarded_for。 - 所有变量在
if块中使用需格外谨慎,部分变量(如$upstream_status)在if中不可用,应优先用map实现条件映射。

















