跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何利用 map 指令动态控制 proxy_cache 开启状态满足不同业务的反代需求

Nginx可通过map指令动态控制proxy_cache开关,核心是用proxy_cache_bypass和proxy_no_cache联动:根据用户身份、请求路径、响应Content-Type等条件生成布尔变量,值为1时跳过缓存并禁止存储,实现精细化缓存启停。 直接用
map
指令控制
proxy_cache
是否生效,核心是把“是否缓存”变成一个可计算的变量,再通过
proxy_cache_bypass
和
proxy_no_cache
联动实现开关效果。它不依赖硬编码的 location 分离,而是按请求特征实时决策,适合多角色、多路径、多内容类型的混合反代场景。 按用户身份动态启停缓存 登录用户看到的内容常需实时性,未登录用户可缓存更久。利用 Cookie 或认证头判断: 在
http
块中定义身份映射: map $cookie_user_id $cache_disabled {" " 0; # 空值(未登录)→ 允许缓存 "default" 1; # 有 user_id → 禁用缓存} 在对应
location
中启用联动: proxy_cache_bypass $cache_disabled;proxy_no_cache $cache_disabled; 注意:
proxy_cache_bypass 1
表示跳过缓存直接回源;
proxy_no_cache 1
表示即使响应本可缓存,也禁止存入本地。两者配合才能彻底隔离登录态。 按请求路径或接口类型关闭缓存 管理后台、调试接口、Webhook 回调等路径天然不适合缓存: 定义路径规则: map $request_uri $bypass_admin_api {"~*^/admin/" 1;"~*^/api/v1/debug" 1;"~*^/webhook/" 1;default 0;} 在反代 location 中写入: proxy_cache_bypass $bypass_admin_api;proxy_no_cache $bypass_admin_api; 正则匹配支持大小写忽略(
~*
),路径前缀加
^
防止误匹配,如
/admin/login
不会触发
/admin_login
。 按响应 Content-Type 决定是否缓存 后端返回 JSON 数据通常不可缓存,而 HTML 或图片可以。关键在于捕获上游响应头: 先确保透传响应头(否则
$upstream_http_content_type
为空): proxy_pass_request_headers on;proxy_buffering on; 再定义类型判断: map $upstream_http_content_type $no_cache_json_html {"~*application/json" 1;"~*text/html" 0;default 0;} 应用到 location: proxy_cache_bypass $no_cache_json_html;proxy_no_cache $no_cache_json_html; 这里
application/json
被设为 1 → 强制不缓存;其他类型默认为 0 → 正常走
proxy_cache_valid
规则。 组合多个条件实现精细开关 单一维度不够时,可叠加判断。Nginx 支持将多个 map 变量并列写入同一指令: 例如:同时满足「是 API 路径」且「返回 JSON」才禁用缓存: map $request_uri $is_api_path {"~*^/api/" 1;default 0;}map $upstream_http_content_type $is_json {"~*application/json" 1;default 0;}# 在 location 中:proxy_cache_bypass $is_api_path $is_json;proxy_no_cache $is_api_path $is_json; 只要任一变量为非 0 值,就会触发 bypass 和 no_cache。这种“或逻辑”设计更安全,避免漏掉某类敏感请求。

相关文章