proxy_cache_bypass 不是“穿透”缓存的技术,而是让 Nginx 主动跳过缓存查找、直接回源的控制指令。所谓“缓存穿透”在这里是误用术语;真正目标是:对特定请求,不读缓存、不依赖旧内容、直连后端——这叫“缓存绕过”。
要让它真正起作用,得满足三个硬条件:缓存已启用、变量写对、值判准。缺一不可。
proxy_cache只写 proxy_cache_bypass 没用。Nginx 会直接忽略它,除非对应 location 明确配置了:
proxy_cache mycache;(名称需与 proxy_cache_path 的 keys_zone 一致)proxy_cache_valid 200 5m;(定义哪些响应可缓存)例如:
location /api/ {
proxy_pass http://backend;
proxy_cache mycache;
proxy_cache_valid 200 302 5m;
proxy_cache_bypass $http_x_refresh;
}
客户端发 X-Refresh: 1,Nginx 内部变量是 $http_x_refresh,不是 $http_X_Refresh 或 $http_xrefresh。规则是:
- 替换为下划线 _$http_常见对照:
X-Bypass-Cache → $http_x_bypass_cacheX-Gray-Preview → $http_x_gray_previewX-Refresh-Cache → $http_x_refresh_cache"0" 或 "off"只要变量展开后满足以下任一,就触发绕过:
"true"、"1"、"force"、"debug")"0"(不区分大小写)"off"(不区分大小写)比如这些都有效:
curl -H "X-Refresh: 1" /api/datacurl -H "X-Refresh: true" /api/datacurl -H "X-Refresh: T" /api/data而这些无效:
curl /api/data(Header 缺失 → 变量为空)curl -H "X-Refresh: 0" /api/datacurl -H "X-Refresh: off" /api/data支持空格分隔多个变量,任意一个为真即绕过:
按 Header 或参数触发:proxy_cache_bypass $http_x_preview $arg_debug;
(带 X-Preview 头,或 URL 含 ?debug=1)
按 IP 白名单限制:proxy_cache_bypass $http_x_refresh $remote_addr ~^(192\.168\.10\.);
用 map 做语义化判断(推荐用于灰度/角色):
map $cookie_role $skip_cache {
"admin" 1;
default 0;
}
proxy_cache_bypass $skip_cache;
proxy_no_cacheproxy_cache_bypass 只控制“不读缓存”,默认仍会把回源响应写入缓存(只要状态码和头符合缓存规则)。这可能导致敏感数据污染缓存。
所以关键补充是:
proxy_no_cache $http_x_refresh;
两个指令变量名必须完全一致,才能确保:
✅ 不查旧缓存
✅ 不存新响应
否则一次管理员调试请求,可能把带 Token 的用户数据缓存下来,被后续无权限用户命中。
别只信配置,实测才可靠:
发起带头请求:curl -I -H "X-Refresh: 1" https://yoursite.com/api/data
检查响应头:
应不含 X-Cache: HIT;理想是看到 X-Cache-Status: BYP(需提前加 add_header X-Cache-Status $upstream_cache_status;)
查 access log:$upstream_cache_status 字段应显示 BYP,不是 HIT 或 MISS
不复杂但容易忽略
Copyright 2026 荣飞网 All Rights Reserved 苏ICP备17039739号-1