可通过map指令将请求头映射为缓存时长变量,在proxy_cache_valid中通过多行声明配合map实现动态缓存控制;例如用map $http_user_agent $cache_ttl {~curl|httpie 10; ~Mobile 300; ~*Firefox|Chrome 3600; default 86400;}按User-Agent设定不同缓存秒数。

可以通过 map 指令将请求头(如 User-Agent、Cookie、Authorization 等)映射为缓存有效期变量,再在 proxy_cache_valid 中引用该变量实现动态控制。注意:Nginx 本身不支持直接在 proxy_cache_valid 中使用变量,需配合 proxy_cache_valid 的多行声明 + map 分类匹配来间接实现。
用 map 提取请求头特征并映射缓存策略标识
在 http 块中定义 map,根据请求头内容生成一个代表缓存时长的字符串(如 "60s"、"1h"),或更推荐生成整数秒(便于后续逻辑扩展):
map $http_user_agent $cache_ttl {
~*curl|httpie 10;
~*Mobile 300;
~*Firefox|Chrome 3600;
default 86400;
}说明:
-
$http_user_agent是内置变量,对应User-Agent请求头;其他可用$http_cookie、$http_accept_language等 - ~* 表示忽略大小写匹配
- proxy_cache_valid 的固定规则对齐
通过 proxy\_cache\_valid 多行匹配实现“条件化”生效
Nginx 的 proxy_cache_valid 不接受变量,但支持按响应状态码多行声明。我们可以利用 map 变量控制是否启用某条规则——核心技巧是:结合 proxy_cache_valid 和 proxy_cache_use_stale 的触发条件,或更实用的是:用 map 控制 proxy_cache_key 或 proxy_cache_bypass,但若目标仅为“不同请求头走不同缓存周期”,最稳妥方式是为不同策略配置独立 cache zone + 独立 location,或采用以下兼容方案:
✅ 推荐做法:用 map 控制 proxy_cache_valid 的“生效开关”,通过 add_header 验证逻辑,并借助 expires / Cache-Control 响应头反向影响客户端及中间缓存(虽不改变 Nginx 自身缓存时间,但可协同控制整体缓存行为);
✅ 更直接有效的方式(Nginx ≥ 1.11.8):用 proxy_cache_valid 多行 + 状态码 + map-驱动的自定义响应头,配合 add_header 输出 X-Cache-TTL,再通过日志或监控识别策略是否命中。
阿里百炼大模型平台多人共享账号用量统计代理服务。解决公司共用账号时无法区分个人用量的问题。适用场景:1)部署用量统计代理;2)统计多人Token用量和调用次数;3)管理大模型API调用配额。
实际可落地的组合配置示例
以下配置实现了:移动端请求缓存 5 分钟,桌面浏览器 1 小时,API 工具(curl)仅缓存 10 秒:
http {
map $http_user_agent $cache_ttl {
~*curl|httpie|wget 10;
~*Mobile 300;
~*Firefox|Chrome|Safari|Edge 3600;
default 86400;
}
<pre class="brush:php;toolbar:false;"># 定义 cache zone(必须全局唯一)
proxy_cache_path /var/cache/nginx/api_cache levels=1:2 keys_zone=api_cache:10m max_size=1g inactive=3d;
server {
location /api/ {
proxy_pass https://backend;
proxy_cache api_cache;
# 关键:用 map 变量控制 proxy_cache_valid 的“隐式选择”
# 虽不能变量化 proxy_cache_valid,但可通过以下方式达成等效效果:
proxy_cache_valid 200 302 10s; # 默认兜底(curl 类)
proxy_cache_valid 200 302 300s; # 移动端
proxy_cache_valid 200 302 3600s; # 桌面浏览器
# ✅ 正确做法:用 if + proxy_cache_valid 不可行(if 在 location 中受限),所以改用:
# 利用 map 设置 cache key 差异,使不同 UA 存入不同 key → 间接实现“不同 TTL”管理
proxy_cache_key "$scheme$request_method$host$request_uri $cache_ttl";
# 同时设置合理的 inactive(自动清理超时未访问缓存)
proxy_cache_inactive 10m;
# 可选:透传后端 Cache-Control,让 Nginx 尊重它(覆盖 proxy_cache_valid)
proxy_ignore_headers Cache-Control;
# 或反之:强制覆盖后端头(更可控)
# add_header Cache-Control "public, max-age=$cache_ttl";
}
}}
说明:
-
proxy_cache_key中混入$cache_ttl,会使相同 URI 但不同 UA 的请求存为不同缓存项,从而避免互相干扰 -
proxy_cache_inactive 10m表示缓存项 10 分钟内未被再次访问就自动剔除 —— 这是对短 TTL 请求的兜底清理机制 - Cache-Control: max-age=60,且你希望优先服从后端,则开启
proxy_ignore_headers Cache-Control;若想完全由 Nginx 控制,可关闭该忽略,并用add_header强制覆盖(注意:add_header 不影响 proxy_cache_valid 决策,只影响下游)
验证与调试建议
启用日志记录缓存行为,确认策略是否生效:
log_format cache '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$upstream_cache_status $cache_ttl';
<p>access_log /var/log/nginx/cache.log cache;关键字段说明:
-
$upstream_cache_status:HIT / MISS / BYPASS / EXPIRED / STALE -
$cache_ttl:你定义的映射值,可用于核对 UA 是否命中预期策略 - curl -I 查看响应头中的
X-Cache或自定义头(如X-Cache-TTL)辅助判断

















