实现动态缓存绕过需用 map 预计算变量(如 $skip_cache),在 proxy_no_cache 和 proxy_cache_bypass 中引用该变量,使其“非空非0”时触发不读不写缓存;配合 X-Cache-Status 等响应头验证行为。

要实现对特定静态请求的动态缓存绕过,关键不是单纯依赖 proxy_no_cache 的布尔开关,而是通过自定义变量控制其值,让 Nginx 在运行时按需决定是否跳过缓存。核心在于:变量必须能被实时计算(如基于请求头、URI、参数或时间),且该变量在 proxy_no_cache 指令中被引用时,Nginx 会将其“非空非0非"0"”的值视为真,从而触发缓存跳过。
定义可变条件:用 map 构建动态标记
直接在 proxy_no_cache 中写复杂逻辑不可行,推荐用 map 块预计算一个布尔型变量。例如,对以 /static/ 开头、且携带 X-Bypass-Cache: true 请求头的 JS/CSS 文件绕过缓存:
map $http_x_bypass_cache $bypass_cache_flag {
default 0;
~*true 1;
}
<p>map $request_uri $is_static_resource {
~<em>^/static/.</em>.(js|css|png|jpg|gif)$ 1;
default 0;
}</p><h1>组合条件:仅当既是静态资源又明确要求绕过时才生效</h1><p>map $is_static_resource:$bypass_cache_flag $skip_cache {
"1:1" 1;
default 0;
}</p>这样 $skip_cache 就是一个运行时可变的开关,值为 1 表示应跳过缓存。
在 proxy_pass 上下文中启用变量驱动的绕过
在 location 块中使用 proxy_no_cache 引用该变量。注意:它接受多个变量或字符串,只要其中任意一个“非空且非 0”,就触发绕过:
location /static/ {
proxy_pass http://backend;
proxy_cache my_cache;
<pre class="brush:php;toolbar:false;"># 关键:引用动态变量
proxy_no_cache $skip_cache;
# 可选:同时兼容其他绕过场景(如带 debug 参数)
proxy_no_cache $skip_cache $arg_debug;
proxy_cache_valid 200 302 10m;
}
此时若请求是 GET /static/app.js?debug=1 且含 X-Bypass-Cache: true,$skip_cache 为 1,$arg_debug 非空,两个条件任一满足即跳过缓存。
配合 proxy_cache_bypass 实现更精细控制
proxy_no_cache 决定“响应是否存入缓存”,而 proxy_cache_bypass 决定“是否跳过缓存直接回源”。两者常配合使用:
-
proxy_cache_bypass $skip_cache;:有绕过标记时,不查缓存,直接发请求到后端 -
proxy_no_cache $skip_cache;:有绕过标记时,即使后端返回了可缓存响应,也不存入缓存 - 二者都设为同一变量,就能做到“既不读缓存,也不写缓存”,真正实现动态绕过
验证与调试技巧
绕过逻辑易出错,建议通过响应头快速确认行为是否生效:
- 添加
add_header X-Cache-Status "$upstream_cache_status";查看是否命中(HIT)、未命中(MISS)或绕过(BYPASS) - 临时加
add_header X-Skip-Cache "$skip_cache";直观检查变量计算结果 - 用
curl -H "X-Bypass-Cache: true" http://example.com/static/main.css手动测试组合条件











