nginx 通过 map 指令按 Content-Type 动态设置 expires 和 Cache-Control,实现下游缓存策略控制;proxy_cache_valid 独立控制 nginx 本地缓存时长,二者协同构成两级缓存。

nginx 中没有直接叫“map 指令实现负载均衡缓存管理”的功能,但你可以用 map + expires + proxy_cache 组合,按文件后缀动态控制响应头中的 Expires 和 Cache-Control,从而影响客户端和中间代理(如 CDN、浏览器)的缓存行为。注意:这不改变 nginx 自身的 proxy_cache 缓存时长(那是由 proxy_cache_valid 控制),而是影响下游如何缓存该响应。
用 map 定义不同后缀对应的缓存时间
在 http 块中定义一个变量,根据请求 URI 后缀映射出缓存秒数:
map $sent_http_content_type $cache_ttl {
default "1h";
~*text/css "7d";
~*text/javascript "7d";
~*application/javascript "7d";
~*image/(jpeg|jpg|png|gif|webp|svg) "30d";
~*font/(woff2?|ttf|eot|otf) "1y";
}说明:
– $sent_http_content_type 是响应头中的 Content-Type,比仅看 URI 后缀更准确(防伪造后缀);
– 正则匹配需加 ~*(忽略大小写);
– 值为标准 nginx 时间单位(s/m/h/d/y),后续传给 expires 指令。
在 location 中启用 expires 并引用 map 变量
在反向代理或静态服务 location 中使用:
location / {
proxy_pass http://backend;
proxy_cache my_cache;
proxy_cache_valid 200 302 10m; # nginx 自身 proxy_cache 缓存时间(独立控制)
<pre class="brush:php;toolbar:false;"># 动态设置响应头缓存策略
expires $cache_ttl;
add_header Cache-Control "public, immutable";}
关键点:
– expires $cache_ttl 会同时设置 Expires 和 Cache-Control: max-age=...;
– 若需更精细控制(如区分 public/private、是否允许 revalidate),可改用 add_header Cache-Control 手动拼接;
– immutable 对静态资源很实用,告诉浏览器该资源不会变,无需条件请求。
配合 proxy_cache 实现两级缓存协同
nginx 的 proxy_cache 和客户端 Cache-Control 是两层机制,应协同设计:
- 后端返回无缓存头?靠
proxy_cache_valid强制缓存,但下游仍可能不缓存 —— 此时expires补上响应头才真正生效; - 后端已返回
Cache-Control: max-age=3600?你的expires $cache_ttl会覆盖它(因在 proxy_pass 后执行); - 想保留后端原始缓存头?去掉
expires,改用add_header Cache-Control ...追加而非覆盖(需确保不冲突)。
验证与调试技巧
检查是否生效最直接的方式是 curl 查看响应头:
curl -I https://example.com/style.css # 应看到:Cache-Control: public, immutable, max-age=604800 # Expires: XXXXXX <p>curl -I <a href="https://www.php.cn/link/c628bded2709eb2b451fdba80e2066ae">https://www.php.cn/link/c628bded2709eb2b451fdba80e2066ae</a> </p><h1>应看到:Cache-Control: public, max-age=3600(默认 1h)</h1>
小技巧:
– 在 map 中加一行 ~*\.(js|css)$ "debug-7d"; 临时测试匹配逻辑;
– 使用 log_format 记录 $cache_ttl,确认每个请求走的是哪个分支;
– 注意:map 变量在 server 或 location 中不可重新定义,必须在 http 块顶层声明。










