nginx 默认缓存键不包含查询参数,需显式用 $uri$is_args$args 等构造唯一缓存键,并过滤敏感参数、叠加租户上下文,再通过响应头和日志验证隔离效果。

Nginx 默认对带参数的请求缓存不够安全——相同 URI 但不同 query 参数(如 /api/list?page=1 和 /api/list?page=2)若未显式纳入缓存键,可能被当成同一缓存项,导致内容错乱或命中错误。关键不是“能不能缓存”,而是“怎么确保每个参数组合生成唯一、可隔离的缓存键”。
显式构造含参数的 proxy_cache_key
默认 $uri 不含查询参数,必须手动加入 $args 或 $is_args$args 才能区分带参请求:
-
$uri$is_args$args:最常用,保留原始参数顺序和编码,例如/search$is_args?q=nginx&sort=desc -
$scheme$request_method$host$uri$is_args$args:更严谨,避免协议/方法差异导致误共享 - 若需忽略某些干扰参数(如
utm_source、_t=时间戳),先用map清洗再拼接
示例:
proxy_cache_key "$scheme$request_method$host$uri$is_args$args";
注意:
$args是原始未解码字符串,Nginx 不会自动标准化参数顺序。若上游服务接受?a=1&b=2和?b=2&a=1视为等价,需在 Nginx 层统一排序(需 Lua 模块),否则两者会生成两个独立缓存项。
避免参数污染缓存(敏感参数绕过)
含认证、调试、追踪类参数的请求不应进入缓存,否则可能缓存私有数据或失效响应:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 用
proxy_no_cache或proxy_cache_bypass跳过:proxy_no_cache $arg_nocache $arg_debug $cookie_auth_token; proxy_cache_bypass $arg_nocache $arg_preview;
- 对特定路径强制不缓存(如含
token=或signature=):set $bypass_cache 0; if ($args ~ "(token|signature|_t=)") { set $bypass_cache 1; } proxy_no_cache $bypass_cache;
多租户/多环境场景下参数+上下文双重隔离
仅靠 $args 不足以应对跨租户、跨环境复用域名的情况。必须叠加可信上下文:
- 若通过
Host区分租户(如tenant-a.example.com):proxy_cache_key "$host$uri$is_args$args";
- 若通过
X-Tenant-ID头识别(由入口网关注入):proxy_cache_key "$http_x_tenant_id$uri$is_args$args";
- 若通过 URL 路径前缀(如
/t/tenant-a/api):map $request_uri $tenant_prefix { ~^/t/(?<t>[^/]+)/ $t; default "unknown"; } proxy_cache_key "$tenant_prefix$uri$is_args$args";</t>
验证是否真正隔离
加响应头和日志字段确认行为:
add_header X-Cache-Status $upstream_cache_status; add_header X-Cache-Key "$scheme$request_method$host$uri$is_args$args"; log_format cache_log '$remote_addr - $upstream_cache_status "$request" "$upstream_http_x_cache_key"'; access_log /var/log/nginx/cache.log cache_log;
这样每条日志都带实际生效的 key 和命中状态,便于排查重复 key 或意外 MISS。
不复杂但容易忽略










