proxy_cache_valid 控制缓存有效期而非缓存频率,需配合状态码、content-type、缓存锁及bypass/no-cache指令协同配置:按状态码设ttl(如200/304缓存1h,5xx仅5s);用map基于$sent_http_content_type动态赋值$cache_ttl;启用proxy_cache_lock防击穿;通过proxy_cache_bypass和proxy_no_cache实现条件绕过。

按 HTTP 状态码设定基础缓存时长
不同状态码语义不同,缓存策略应区别对待:
- 成功响应(200/206/304):通常最值得缓存,例如静态资源或稳定 API
- 重定向(301/302):可缓存但时间不宜过长,避免跳转逻辑变更后仍返回旧地址
- 客户端错误(404/403):可缓存短时间(如 1–5 分钟),减少对无效路径的重复回源
- 服务端错误(5xx):一般不缓存,或仅作极短兜底(如 5s),避免把故障响应长期固化
示例:
proxy_cache_valid 200 206 304 1h;proxy_cache_valid 301 302 10m;
proxy_cache_valid 404 403 5m;
proxy_cache_valid 500 502 503 504 5s;
按 Content-Type 动态设置缓存时长
同一状态码下,不同资源类型更新节奏差异大。Nginx 原生不支持按响应头动态设 TTL,但可通过 map 指令 + $sent_http_content_type 实现:
- 匹配上游返回的
Content-Type(注意不是请求头$http_content_type) - 映射出变量(如
$cache_ttl),再在proxy_cache_valid中引用 - 规则顺序很重要:更具体的类型(如
application/json)要放在通用类型(如application/)之前
示例(放在 http 块中):
default "5s";
~*^text/ "1h";
~*^application/javascript "1h";
~*^image/ "24h";
~*^application/json "10s";
}
然后在 location 中使用:
proxy_cache_valid 200 302 $cache_ttl;启用缓存锁防止缓存击穿
当大量并发请求同时命中未缓存资源时,若不做控制,所有请求都会穿透到上游,造成瞬时压力高峰。
- 开启
proxy_cache_lock on:只允许第一个请求回源,其余等待缓存生成后直接读取 - 配合
proxy_cache_lock_age 5s:若首个请求超时未返回,释放锁让新请求尝试回源 - 这对 API 或动态页面尤其重要,能显著降低后端负载峰值
配合 bypass 和 no-cache 控制绕过逻辑
某些请求不该走缓存(如带认证 token、调试参数、POST 请求),需主动排除:
-
proxy_cache_bypass $arg_nocache $cookie_nocache:遇到指定参数或 Cookie 就跳过缓存 -
proxy_no_cache $arg_debug $http_pragma:不仅不读缓存,也不写入缓存 - 注意:
proxy_cache_bypass是“读时不缓存”,proxy_no_cache是“读+写都不缓存”
常见组合:
proxy_cache_bypass $arg_nocache $cookie_admin;proxy_no_cache $http_pragma $http_authorization;











