核心请求变量(最常用)
1. 连接/客户端信息
| 变量 |
说明 |
示例值 |
$remote_addr |
客户端IP地址 |
192.168.1.100 |
$remote_port |
客户端端口 |
54321 |
$remote_user |
HTTP基本认证用户名 |
alice |
$server_addr |
服务器接收请求的IP |
10.0.0.1 |
$server_port |
服务器接收请求的端口 |
80, 443 |
2. 主机/域名信息
| 变量 |
区别 |
示例 |
$host |
请求头中的 Host 字段(不含端口) |
example.com |
$http_host |
同 $host,但包含端口(如果有) |
example.com:8080 |
$server_name |
匹配的 server 块名称 |
www.example.com |
详细对比:
# 请求:GET / HTTP/1.1 Host: www.example.com:8080
$host = "www.example.com" # ← 最常用
$http_host = "www.example.com:8080" # 带端口
$server_name = "default" # 匹配的server名称
3. 请求信息
| 变量 |
说明 |
示例 |
$request |
完整的原始请求行 |
GET /api/user?name=john HTTP/1.1 |
$request_method |
HTTP方法 |
GET, POST, PUT |
$request_uri |
完整的URI(带参数) |
/api/user?name=john |
$uri |
当前请求的URI(不含参数) |
/api/user |
$document_uri |
同 $uri |
/api/user |
$args |
查询字符串 |
name=john&age=20 |
$query_string |
同 $args |
name=john&age=20 |
$is_args |
如果有参数则为"?",否则为空 |
? |
$arg_XXX |
获取特定查询参数 |
$arg_name = "john" |
$request_body |
请求体内容(POST/PUT) |
{"id":1} |
$request_length |
请求长度(字节) |
125 |
$request_time |
请求处理时间(秒,毫秒精度) |
0.123 |
4. 头部信息
| 变量 |
说明 |
$http_XXX |
获取请求头(XXX转为小写,横线变下划线) |
$sent_http_XXX |
获取响应头 |
示例:
# 获取各种头部
$http_user_agent # User-Agent 头
$http_referer # Referer 头
$http_content_type # Content-Type 头
$http_x_forwarded_for # X-Forwarded-For 头
$sent_http_content_type # 响应 Content-Type
响应相关变量
1. 响应状态
| 变量 |
说明 |
示例 |
$status |
HTTP响应状态码 |
200, 404, 500 |
$body_bytes_sent |
发送给客户端的响应体字节数 |
1024 |
$bytes_sent |
发送的总字节数 |
1500 |
$connection |
连接序列号 |
12345 |
$connection_requests |
当前连接已处理的请求数 |
5 |
2. 响应头控制
# 常用于 add_header 指令
add_header X-Request-ID $request_id;
add_header X-Response-Time $request_time;# 返回特定状态码
return 200 "Request ID: $request_id";
代理相关变量
1. 反向代理变量
| 变量 |
说明 |
$proxy_host |
proxy_pass 指令中指定的主机 |
$proxy_port |
proxy_pass 指令中指定的端口 |
$proxy_add_x_forwarded_for |
追加IP到 X-Forwarded-For |
$proxy_protocol_addr |
PROXY协议中的客户端地址 |
2. 上游服务器变量
| 变量 |
说明 |
$upstream_addr |
后端服务器地址 |
$upstream_status |
后端响应状态码 |
$upstream_response_time |
后端响应时间(秒) |
$upstream_connect_time |
连接后端时间 |
$upstream_header_time |
接收后端响应头时间 |
$upstream_cache_status |
缓存状态 |
示例配置:
log_format upstream_debug '$remote_addr - $upstream_addr - ''upstream_response_time=$upstream_response_time - ''upstream_cache_status=$upstream_cache_status';
SSL/TLS 相关变量
HTTPS 连接信息
| 变量 |
说明 |
示例 |
$scheme |
请求协议 |
http, https |
$https |
如果是HTTPS则为"on",否则为空 |
on |
$ssl_protocol |
SSL协议版本 |
TLSv1.2 |
$ssl_cipher |
协商的加密套件 |
ECDHE-RSA-AES256-GCM-SHA384 |
$ssl_session_id |
SSL会话ID |
a1b2c3... |
$ssl_session_reused |
会话是否重用 |
r |
$ssl_client_serial |
客户端证书序列号 |
1234567890 |
$ssl_client_s_dn |
客户端证书主题 |
CN=John Doe, O=Example Inc. |
$ssl_client_verify |
客户端证书验证结果 |
SUCCESS, FAILED |
SSL配置示例:
server {listen 443 ssl;ssl_certificate /path/to/cert.pem;ssl_certificate_key /path/to/key.pem;location /secure {# 记录SSL信息access_log /var/log/nginx/ssl.log '$ssl_protocol $ssl_cipher';# 要求客户端证书if ($ssl_client_verify != SUCCESS) {return 403;}}
}
时间和日期变量
时间格式变量
| 变量 |
格式 |
示例 |
$time_local |
本地时间(通用日志格式) |
18/Dec/2025:10:30:45 +0800 |
$time_iso8601 |
ISO 8601 格式 |
2025-12-18T10:30:45+08:00 |
$msec |
当前时间(秒.毫秒) |
1671337845.123 |
$request_time |
请求处理时间 |
0.123 |
$upstream_response_time |
后端响应时间 |
0.056 |
日志时间配置:
# 推荐使用 ISO 8601 格式,便于解析
log_format json_log '{"@timestamp":"$time_iso8601", "request":"$request"}';# 传统格式(兼容旧系统)
log_format combined '$remote_addr - $remote_user [$time_local] "$request"';
特殊用途变量
1. 速率限制相关
| 变量 |
说明 |
$limit_rate |
客户端传输速率限制(可设置) |
$connection |
连接序列号 |
$connection_requests |
当前连接请求数 |
2. GeoIP 模块变量
# 需要 ngx_http_geoip_module 模块
geoip_country /etc/nginx/GeoIP.dat;location / {# 获取地理位置信息add_header X-Country $geoip_country_code;add_header X-City $geoip_city;
}
3. Real IP 模块变量
# 从代理头获取真实IP
real_ip_header X-Forwarded-For;
set_real_ip_from 10.0.0.0/8;# 变量变化
# $remote_addr 变为真实客户端IP
# $realip_remote_addr 保存原 $remote_addr
实际应用场景
场景1:日志增强
log_format enhanced '$remote_addr - "$http_user_agent" - ''"$request" $status $body_bytes_sent - ''Referer: "$http_referer" - ''Forwarded: "$http_x_forwarded_for" - ''Upstream: $upstream_addr ($upstream_response_time s) - ''SSL: $ssl_protocol/$ssl_cipher';
场景2:动态代理配置
# 根据请求头动态选择后端
map $http_x_api_version $backend {default "http://api-v1:8080";"v2" "http://api-v2:8080";
}location /api {proxy_pass $backend;
}
场景3:安全限制
# 限制特定User-Agent
if ($http_user_agent ~* (wget|curl|bot)) {return 403 "No bots allowed";
}# 检查必要的请求头
if ($http_x_api_key = "") {return 401 "API key required";
}
场景4:A/B测试
# 基于Cookie的路由
map $cookie_experiment $backend_group {"A" "backend_a";"B" "backend_b";default "backend_default";
}upstream backend_a { server 10.0.0.1:8080; }
upstream backend_b { server 10.0.0.2:8080; }
upstream backend_default { server 10.0.0.3:8080; }location / {proxy_pass http://$backend_group;
}
场景5:调试信息
location /debug {# 返回所有变量信息return 200 "Host: $host\nRemote: $remote_addr\nURI: $uri\nArgs: $args\nMethod: $request_method\nScheme: $scheme\nUser-Agent: $http_user_agent\nReferer: $http_referer\nTime: $time_iso8601\n";
}
变量优先级与作用域
变量作用域
- 请求级别:大多数变量(如
$uri, $args)
- 连接级别:
$connection, $connection_requests
- 服务器级别:
$server_name, $server_addr
常见陷阱
# ❌ 错误:在 server 作用域使用请求级别变量
server {# $uri 在这里是 undefined!set $fixed_uri $uri; # 错误!location / {# ✅ 正确:在 location 中使用set $fixed_uri $uri;}
}# ❌ 变量不能嵌套
set $original_host $host;
set $new_host "$original_host:8080"; # ✅ 可以
set $new_host "${host}:8080"; # ❌ 不能嵌套
常用变量速查表
基础三要素
$host # 域名(无端口)
$remote_addr # 客户端IP
$request_uri # 完整路径+参数
代理必备
$proxy_add_x_forwarded_for # 追加代理链
$upstream_addr # 后端地址
$upstream_response_time # 后端响应时间
SSL相关
$scheme # http/https
$ssl_protocol # TLS版本
$ssl_cipher # 加密套件
时间相关
$time_iso8601 # ISO时间(推荐)
$request_time # 请求处理时间
头部访问
$http_xxx # 请求头(xxx转小写,-转_)
$sent_http_xxx # 响应头
最佳实践建议
- 日志格式化:使用
$time_iso8601 而不是 $time_local
- 代理设置:总是传递
Host 和 X-Real-IP 头部
- 安全考虑:不要在生产环境暴露
$request_body 等敏感信息
- 性能监控:记录
$request_time 和 $upstream_response_time
- 调试技巧:创建
/debug 端点返回关键变量值