实现缓存隔离需构造唯一缓存键:按子域名用$host或X-Tenant-ID提取租户;按路径前缀用location正则捕获biz_group;按角色需可信header注入并清空客户端同名头;多维组合时固定顺序、显式分隔符、空值兜底、过滤非法字符、包含$scheme防协议冲突。

要实现不同业务维度的缓存隔离,核心是让 proxy_cache_key 生成唯一、可区分的缓存键,确保相同业务请求打到同一缓存项,不同业务互不干扰。关键在于把能标识业务维度的变量(如子域名、URL路径前缀、请求头、参数等)稳定、安全地拼入缓存键。
按子域名或租户标识隔离
多租户 SaaS 场景中,不同客户访问同一域名下的不同子域(如 tenant-a.example.com、tenant-b.example.com),可通过 $host 或自定义 header 提取租户 ID:
- 直接使用
$host:适合子域即租户 ID 的场景,例如proxy_cache_key "$host$request_uri $scheme"; - 提取自定义 header:若通过
X-Tenant-ID传递租户信息,先用map做校验与标准化:
map $http_x_tenant_id $tenant_key {
default "unknown";
~^[a-z0-9\-]{3,32}$ $http_x_tenant_id;
}
再在 key 中引用:proxy_cache_key "$tenant_key$request_uri $scheme";
按业务线或 API 分组隔离
同一域名下多个业务线共用后端(如 /shop/、/pay/、/user/),应避免跨业务缓存污染:
- 用
$1捕获路径前缀:
location ~ ^/(shop|pay|user)/ {
set $biz_group $1;
proxy_cache_key "$biz_group$request_uri $scheme $http_accept_language";
} - 对 GraphQL 或统一网关接口,可解析 query 参数中的
service字段(需配合map或 Lua 模块提取),但更推荐由上游透传标准化 header(如X-Biz-Service: order)。
按用户角色或权限级别隔离(谨慎使用)
仅适用于读接口中「内容随角色变化但无需强实时」的场景(如运营后台的仪表盘摘要),不建议用于高频或敏感数据:
- 依赖可信 header(如认证服务注入的
X-User-Role):proxy_cache_key "$http_x_user_role$request_uri $scheme"; - 必须确保该 header 不被客户端伪造——应在入口层(如 auth proxy)统一注入,并移除客户端原始同名 header;
Nginx 配置示例:
proxy_set_header X-User-Role ""; # 清空客户端传入
proxy_pass_request_headers off; # 可选,彻底禁用客户端 header - 注意:加入用户级变量会大幅降低缓存命中率,需评估业务容忍度与资源开销。
组合维度与缓存键稳定性保障
多个维度叠加时,顺序、分隔符和标准化决定键的可靠性:
- 固定顺序 + 显式分隔符:如
"$host|$biz_group|$tenant_key|$request_uri",避免$host$request_uri在 host 以数字结尾、uri 以数字开头时产生歧义(如abc123.example.com+/123api→ 键变成abc123.example.com/123api,易与abc123.example.com123/api冲突) - 对可能为空或含特殊字符的变量做兜底处理:用
map将空值转为"none",用perl_set或ngx_http_lua_module过滤非法字符(如空格、控制符) - 始终包含协议(
$scheme)或显式指定 HTTPS,避免 HTTP/HTTPS 请求误共享缓存


















