必须将租户身份固化进缓存键并隔离缓存区域——通过server_name或header提取租户名,构造含租户标识的proxy_cache_key;为各租户配置独立keys_zone和物理缓存路径;按sla分级设置ttl与stale策略;通过日志、响应头验证隔离效果,敏感接口禁用缓存。

不能只靠路径或响应状态缓存,必须把租户身份固化进缓存键里——否则 tenant-a 和 tenant-b 请求同一接口,可能拿到对方的缓存内容。
缓存键必须携带租户标识
默认用 $request_uri 或 $host 生成 key,会跨租户复用缓存。要强制注入租户上下文:
- 在 server 块中已通过
server_name ~^(?<tenant>[a-z0-9\-]+)\.api\.example\.com$</tenant>提取租户名后,定义缓存 key 时显式包含:proxy_cache_key "$tenant|$scheme|$request_method|$host|$request_uri"; - 若用 header 识别(如
X-Tenant-ID),则 key 应为:proxy_cache_key "$http_x_tenant_id|$scheme|$request_method|$host|$request_uri"; - 对非法或空租户值,Nginx 层应拦截(
if ($tenant = "") { return 400; }),避免生成无效缓存键
每个租户配独立缓存区域
共用 keys_zone 会导致元数据竞争和清理策略冲突:
- 在 http 块中为不同租户声明隔离的缓存区:
proxy_cache_path /data/nginx/cache/tenant-a levels=1:2 keys_zone=cache_a:5m max_size=2g inactive=30m;proxy_cache_path /data/nginx/cache/tenant-b levels=1:2 keys_zone=cache_b:5m max_size=2g inactive=30m; - 对应 server 块内启用专属缓存:
proxy_cache cache_a;proxy_cache_valid 200 302 10m; - 目录物理分离,便于按租户清理:
rm -rf /data/nginx/cache/tenant-a/*
缓存策略按租户分级控制
不同租户对一致性、延迟、容错要求不同,不能统一 TTL:
- 高 SLA 租户(如付费客户):缓存时间短(
proxy_cache_valid 200 302 30s),启用stale_while_revalidate保证降级可用性 - 低优先级租户(如试用账户):TTL 更短(
5s),且禁用 stale 策略,直接穿透,避免污染高价值缓存空间 - 所有租户均关闭
proxy_cache_lock(防止锁等待放大延迟),改用轻量级proxy_cache_lock_age 1s
可观测性与安全兜底
缓存是否真隔离,得靠日志和响应头验证:
- 日志格式中固定记录租户与缓存状态:
log_format tenant_cache '$remote_addr "$request" $status $upstream_cache_status "$http_x_tenant_id" $tenant'; - 响应头显式标注租户与缓存行为:
add_header X-Cache "$upstream_cache_status";add_header X-Tenant-Name "$tenant"; - 敏感接口(如 /user/profile)禁止缓存:
location /user/ { add_header Cache-Control "no-store, no-cache"; proxy_cache_bypass 1; }











