Nginx默认proxy_cache_key包含全部请求变量导致缓存碎片化;应仅保留影响响应内容的字段,如$scheme$host$uri用于静态资源,配合map提取device、cache_user_id等稳定变量,并用cache_bypass/no_cache控制穿透逻辑。

直接用默认 proxy_cache_key,Nginx 会把整个 $request_uri(含所有 query 参数、$http_user_agent、$http_cookie)原样拼进去。结果就是:同一张图片、同一个 API 接口,因为带了 utm_source=weibo 或 sessionid=abc123 就生成完全不同的缓存项——命中率暴跌,磁盘白白占用,回源压力不降反升。
只留真正影响内容的变量
缓存键不是越“全”越好,而是越“准”越好。核心原则是:只有导致后端返回不同响应的字段,才放进 key。
- 静态资源(JS/CSS/图片)通常只需
$scheme$host$uri—— 路径不变,内容就不该变 - SSR 页面(如 Next.js)要保留
lang、region、theme这类服务端路由参数,但过滤掉utm_*、ref=、fbclid=等纯埋点参数 - 登录态页面若需区分用户,只取关键 Cookie 字段(如
session-token),而非整段$http_cookie
用 map 提前归类 UA 和提取 Cookie
避免在 proxy_cache_key 行内写正则或复杂逻辑。推荐用 map 指令提前提取干净、稳定的变量:
安全更新和维护 CLI Proxy API(CPA)部署与配置。用于 CPA 镜像升级、配置变更、认证目录兼容修复、上线验证与回滚。适用于用户提到“CPA 更新/升级/配置改了/容器重建/回滚”等场景。
- 按设备类型归类 UA:
map $http_user_agent $device {
~*(iPhone|Android|Mobile) "mobile";
~*iPad "tablet";
default "desktop";
} - 提取指定 Cookie 值:
map $http_cookie $cache_user_id {
~session-token=([^;]+) $1;
default "guest";
} - 最终 key 示例:
proxy_cache_key "$scheme$host$request_uri|$device|$cache_user_id";
配合 cache_bypass 和 no_cache 控制穿透逻辑
精准 key 解决了“该缓存什么”,而 proxy_cache_bypass 和 proxy_no_cache 决定“什么时候不缓存”:
- 开发调试时加
?nocache=1:proxy_cache_bypass $arg_nocache;直连后端 - 登录用户访问个人页,可设
proxy_no_cache $cookie_session_token;—— 有 session 就不缓存(或仅缓存片段) - 灰度发布时用特定 Header 控制,例如
proxy_cache_bypass $http_x_abtest_flag;
验证是否生效,别跳过这步
改完 key 后必须确认是否按预期工作:
- 配置
add_header X-Cache-Status $upstream_cache_status;,观察响应头中HIT/MISS/BYPASS分布 - 用
log_format记录真实生成的 key:
log_format cache_log "$time_local $upstream_cache_status $cache_key";
抽样检查日志,确认移动端和 PC 端、不同用户 ID 是否生成了合理分离的 key - 若 key 中含
$cookie_user_id或$device,就无法再用“按 URL 刷新”,必须改用“按 Cachekey 刷新”,建议 key 开头加业务前缀,如"api_v2:$scheme://$host$request_uri:$device"

















