Nginx 通过 map 指令基于 $sent_http_content_type 动态设置 proxy_cache_valid,实现不同 Content-Type 响应差异化缓存时效,如 CSS/JS 缓存 1 小时、JSON 缓存 10 秒,无需重启即可热加载生效。

直接用 map 指令基于响应头中的 Content-Type 动态设置 proxy_cache_valid,是应对生产环境内容紧急更迭最轻量、最可控的方式——不依赖后端改代码,不重启 Nginx,也不需要清缓存,只需一次配置热加载,就能让不同资源按需“活”得久或“死”得快。
为什么 map 是紧急更迭的首选机制
当产品上线新版本、修复关键 bug 或调整 API 格式时,往往伴随两类资源更新节奏差异:前端静态资源(CSS/JS/字体)可长期缓存,而 JSON 接口响应可能秒级失效。硬编码统一 TTL 会引发两种风险:缓存太久导致用户看到旧接口数据;缓存太短又拖垮后端。而 map 在请求返回瞬间读取 $sent_http_content_type,实时决定该响应该缓存多久,天然适配“什么内容就配什么寿命”的弹性需求。
核心配置要点与避坑细节
必须在 http 块中定义,且规则顺序直接影响结果:
- 使用
$sent_http_content_type(不是$http_content_type),它代表上游实际返回的类型,确保真实反映内容性质 - 正则匹配加
~*忽略大小写,例如~*^application/json能覆盖application/json; charset=utf-8 - 把具体类型放前面,通用类型放后面:先写
application/json,再写application/,否则后者会提前截断匹配 -
default "5s"是安全兜底,防止未匹配时变量为空导致proxy_cache_valid解析失败
如何快速响应一次线上变更
假设某次发布将用户资料接口从 text/html 改为 application/json,但旧缓存尚未过期,用户持续看到错误渲染页。此时无需清缓存,只需两步:
- 在 map 中新增一行:
~*^text/html "10s";,将 HTML 类型响应缓存时间压到 10 秒内 - 执行
nginx -t && nginx -s reload,配置即时生效,10 秒后所有旧 HTML 缓存自动失效,新 JSON 响应按既定策略(如 10s)接管
配合 bypass 实现“灰度验证+全量切换”双模式
仅靠动态 TTL 还不够灵活。可叠加 proxy_cache_bypass 实现更精细控制:
- 开发调试时,加请求头
X-Refresh: 1,直连后端看最新效果,不受任何 TTL 影响 - 上线初期,对特定路径(如
/api/v2/user)临时加proxy_cache_bypass $arg_force_refresh;,通过?force_refresh=1参数触发绕过,供 QA 验证 - 确认无误后,删掉 bypass 规则,让 map 控制的 TTL 自然接管,完成平滑过渡











