Nginx 实现复杂路由缓存需解耦路由决策与缓存控制,用 map 指令动态设置缓存时效,结合精细化 cache_key、bypass 机制及权限与状态码校验确保缓存准确生效。

要让 Nginx 缓存适配复杂路由逻辑,关键不是靠 location 嵌套堆砌,而是把“路由决策”和“缓存控制”解耦——前者决定请求发给谁,后者决定是否缓、缓多久、缓哪部分。硬塞在同一个 location 里容易失效或冲突。
用 map 指令实现差异化缓存时效
单一 location 无法对不同路径设置不同缓存时间,但 map 可以按请求特征动态生成变量,再交给 proxy_cache_valid 使用:
- 在 http 块定义映射规则,例如区分静态资源、API 和健康检查接口:
map $request_uri $cache_ttl {
~^/static/ "30d";
~^/api/v1/ "5m";
~^/healthz "0s";
default "1m";
}
- 在对应 location 中引用该变量(注意:仅支持时间值,不能用于开关缓存):
location / {
proxy_cache my_cache;
proxy_cache_valid 200 $cache_ttl;
proxy_pass http://backend;
}
这样 /static/logo.png 缓 30 天,/api/v1/user 缓 5 分钟,/healthz 则不缓存(0s 表示跳过缓存)。
缓存键必须包含影响内容的全部维度
默认 $request_uri 不含查询参数或 Header,会导致缓存污染:
- 带参数的 URL(如 /search?q=nginx)需显式加入 $args,否则所有 q 参数都被当成同一缓存项;
- 多语言站点需考虑 Accept-Language,可构造 key:proxy_cache_key "$scheme$request_method$host$request_uri$http_accept_language";
- 用户登录态接口若需缓存,必须排除 Cookie 影响:加 proxy_ignore_headers Set-Cookie;,并确认后端已剥离敏感头。
绕过缓存与强制刷新的可控机制
生产中常需临时跳过缓存或主动失效,Nginx 提供了轻量级方案:
- 按请求头控制(如内部调试):proxy_cache_bypass $http_x_cache_bypass;,当 header 为非空值时跳过缓存;
- 按状态码启用 stale 缓存:proxy_cache_use_stale error timeout http_500;,后端挂了也能返回旧数据保可用;
- 配合 purge 模块(需编译安装)或利用缓存路径哈希手动清理,但更推荐用版本化 URL 或 cache_key 设计规避 purge 需求。
权限与响应条件必须严格校验
缓存配置生效前,两个隐性门槛常被忽略:
- 目录权限:proxy_cache_path 的父目录(如 /var/cache/nginx)必须由 Nginx worker 用户(如 www-data)可写,root 所有会静默失败;
- 响应状态码限制:proxy_cache_valid 200 10m; 对 304、502 等响应无效,需单独声明,例如:proxy_cache_valid 200 304 10m;;
- 默认不缓存 Set-Cookie 或 Authorization 请求,如有需要,必须显式忽略:proxy_ignore_headers Set-Cookie; + proxy_cache_key 中剔除用户标识字段。



















