关键在于按资源稳定性分层控制缓存:带哈希文件设长缓存+immutable,无哈希文件设短周期,动态入口禁用强缓存;alias仅负责路径映射,缓存指令必须与alias同location块生效。

在 alias 映射下处理大批量静态文件的缓存过期,关键不是“统一设个时间”,而是按资源稳定性与更新机制分层控制:带哈希的文件大胆长缓存,无哈希的设合理短周期,动态入口类资源必须禁用强缓存。alias 本身不决定缓存,它只负责路径映射;缓存行为完全由 location 块内的 expires 和 Cache-Control 共同生效。
必须和 alias 写在同一个 location 块里
expires 或 add_header Cache-Control 不会跨块继承。如果 alias 在 location /static/ {} 中,那所有缓存指令也得放进去,否则压根不生效:
- ✅ 正确写法:
location /static/ {
alias /data/assets/;
expires 1y;
add_header Cache-Control "public, immutable, max-age=31536000";
} - ❌ 错误写法:把 expires 放在 server 块顶层或另一个 location 里,对 /static/ 下的请求无效
按文件是否含 contenthash 分级配置
哈希值变 → URL 变 → 浏览器自然弃旧取新。这是最省心、最可靠的缓存失效方式:
- JS/CSS/字体(如 app.f3e8d2.js、style.b9a1c4.css):配 expires max + immutable,浏览器不会发验证请求,真正“一次加载、长期免查”
- 图片、图标、文档(如 logo.png、manual.pdf):名不变但内容可能更新,设 expires 30d + Cache-Control "public, max-age=2592000"
- HTML、XML、JSON 接口响应:即使走 alias 提供(比如 /api/status.json),也必须 expires epoch + "no-cache, must-revalidate",避免缓存污染
避免正则匹配误伤,优先用前缀匹配 + 精准后缀过滤
alias 常用于固定路径(如 /static/、/assets/),这时别用 location ~* \.js$ 这类全局正则——容易把 /static/app.js 和 /api/v1/js 的响应都套上长缓存,后者可能是动态接口。
- 推荐组合:
location ^~ /static/ {
alias /data/assets/;
# 只对 static 下的静态后缀生效
location ~* \.(js|css|woff2|svg|webp)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location ~* \.(png|jpg|gif|pdf)$ {
expires 30d;
}
} - ^~ 保证前缀匹配优先级高,内部嵌套 location 实现细粒度控制,性能好还不怕冲突
配合 open_file_cache 减少系统开销
alias 指向的目录若含数万小文件(比如图标库、用户头像),反复 stat() 是隐形瓶颈。开启文件元数据缓存能显著降低内核调用次数:
- 在 http 块中加:
open_file_cache max=10000 inactive=60s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on; - 它缓存的是“文件是否存在、大小、最后修改时间”,不是文件内容,对 alias 和 root 同样有效
- min_uses 2 可过滤掉爬虫或测试请求,避免缓存被低频访问条目占满











