缓存时间不生效主因是proxy_cache_valid被后端响应头(如cache-control: no-cache)覆盖或未匹配实际状态码,需用curl -i查原始头、add_header输出x-cache-status验证运行时行为,并确保proxy_ignore_headers和作用域配置正确。

缓存时间不生效,通常不是因为没写 proxy_cache_valid,而是它被其他配置覆盖、忽略或压根没匹配到响应。关键要确认:Nginx 实际采用的是哪条缓存规则,以及为什么没按你写的时长执行。
看响应头和日志,确认真实生效的缓存策略
别只查配置文件,得验证运行时行为:
- 用
curl -I请求目标 URL,检查响应头中Cache-Control和Expires的值——它们可能来自后端,而非 Nginx 配置 - 在 location 块中加
add_header X-Cache-Status $upstream_cache_status;和add_header X-Cache-Time $upstream_http_expires;,直观看到缓存状态和过期时间来源 - 在 log_format 中加入
$upstream_cache_status和$upstream_http_cache_control,查 access.log 看每条请求实际走的是 HIT/MISS/EXPIRED,以及后端返回了什么缓存头
检查 proxy_cache_valid 是否被响应头覆盖
Nginx 默认会优先信任后端返回的 Cache-Control 或 Expires,哪怕你写了 proxy_cache_valid 200 10m,只要后端返回 Cache-Control: no-cache 或 max-age=0,这条响应就不会进缓存。
- 先用
curl -I查后端原始响应头,确认是否存在no-cache、private、no-store或非法max-age - 若存在,必须在对应 location 中加
proxy_ignore_headers Cache-Control Expires;(注意:不要加ETag或Last-Modified,除非它们真有问题) - 确保
proxy_cache_valid明确覆盖了实际返回的状态码,比如后端返回 200,但配置只写了proxy_cache_valid 404 1m,那 200 就完全不会被缓存
排查作用域与继承关系导致的规则失效
缓存有效期不是全局生效的,它严格依赖配置所在的作用域:
-
proxy_cache_valid必须写在有proxy_pass的 location 块里,写在 server 或 http 块中不会自动继承到所有子 location - 多个 location 匹配同一请求时,Nginx 按最长前缀或正则优先级选择,可能你改了 A location 的
proxy_cache_valid,但请求实际进了 B location - 如果用了
if块包裹proxy_cache_valid,该指令在 if 中是不合法的,会被静默忽略
验证缓存是否真的写入并按预期过期
即使配置“看起来”对了,也可能因路径、权限或 keys_zone 不足导致缓存根本没落地:
- 进入缓存目录(如
/var/cache/nginx),用find . -type f -mmin -5 | head -5查最近生成的缓存文件,再用stat看修改时间,判断是否真按你设的 10m 过期 - 检查
proxy_cache_path定义里的inactive=参数——它控制“多久没被访问就自动删除”,若设得太小(如inactive=1m),即使proxy_cache_valid是 10m,缓存也可能 1 分钟不用就被清理 - 确认
keys_zone内存足够:每个缓存项元信息约占用 512 字节,若 QPS 是 1000,平均缓存生命周期 600 秒,至少需keys_zone=my_cache:128m,否则索引满后新缓存无法写入,看似“不生效”











