通过map指令动态控制proxy_cache,将租户标识映射为$tenant_id,并据此设定$cache_bypass、$cache_zone和$cache_ttl,实现多租户差异化缓存策略,避免if性能损耗且保障隔离性。

用 map 指令动态控制 proxy_cache 开启状态,核心是把“是否缓存”转化为一个可计算的变量(比如 $cache_enabled),再通过 proxy_cache_bypass 或 proxy_no_cache 关联该变量,实现按租户条件开启或关闭缓存。它不依赖 if 块,性能稳定,适合多租户场景中对不同客户差异化启用加速能力。
定义租户识别变量
先从请求中提取租户标识,常用来源包括 Host、子域名、请求头或 Cookie:
- 按子域名识别:map $host $tenant_id { ~^([a-z0-9\-]+)\.example\.com$ $1; default "default"; }
- 按请求头识别:map $http_x_tenant_id $tenant_id { "" "anonymous"; default $http_x_tenant_id; }
- 按 Cookie 提取用户组:map $cookie_tenant_group $tenant_id { "~^pro$" "pro"; "~^basic$" "basic"; default "free"; }
映射缓存开关与策略
基于 $tenant_id 决定是否启用缓存,并可同时设定 TTL 和 cache_zone:
- 缓存开关变量(用于 bypass):map $tenant_id $cache_bypass { "pro" ""; "basic" ""; "free" "1"; "anonymous" "1"; }
- 专属缓存区域:map $tenant_id $cache_zone { "pro" "pro_cache"; "basic" "basic_cache"; default "shared_cache"; }
- 差异化过期时间:map $tenant_id $cache_ttl { "pro" "10m"; "basic" "2m"; default "30s"; }
注意:$cache_bypass 设为非空值(如 "1")表示跳过缓存;设为空字符串 "" 表示允许缓存。proxy_cache_bypass 会直接绕过整个缓存流程,比 proxy_no_cache 更彻底。
在 location 中联动生效
将 map 变量注入反向代理配置,确保每个租户走独立逻辑:
- 指定缓存区:proxy_cache $cache_zone;
- 控制是否进入缓存流程:proxy_cache_bypass $cache_bypass;
- 设置响应有效期:proxy_cache_valid 200 302 $cache_ttl;
- 构造防污染 key(可选):proxy_cache_key "$tenant_id:$scheme://$host$request_uri$is_args$args";
这样,pro 租户请求命中 pro_cache 区域、缓存 10 分钟且不 bypass;free 租户则始终 bypass,不写入任何缓存,保障其数据实时性。
验证与隔离要点
多租户缓存必须避免跨租户响应混用,关键检查项包括:
- 所有 map 必须有 default 分支,防止变量为空导致 proxy_cache_bypass 解析异常
- proxy_cache_path 需为各 zone 单独声明(如 keys_zone=pro_cache:5m),不能共用同一 zone 名
- 用 add_header X-Tenant-Cache $upstream_cache_status; 辅助调试,确认不同租户的缓存状态是否符合预期
- 若上游返回 Cache-Control: no-cache,需加 proxy_ignore_headers Cache-Control; 否则会覆盖 map 的策略


















