静态资源缓存失效本身不直接导致抖动,但会引发请求穿透、后端压力陡增或磁盘I/O激增,表现为延迟升高、CPU/IO尖峰、5xx上升;排查重点是“为何本该命中的缓存未起作用并引发连锁负载恶化”。

静态资源缓存失效本身不会直接导致性能抖动,但当它引发大量请求穿透、后端压力陡增或磁盘 I/O 激增时,就会在系统层面表现为延迟升高、CPU/IO 尖峰、5xx 上升等抖动现象。排查重点不是“缓存有没有命中”,而是“为什么本该命中的缓存没起作用,且造成了连锁负载恶化”。
确认缓存是否真实失效,而非配置未生效
很多所谓“缓存失效”其实是配置压根没加载成功:
- 先执行 sudo nginx -t,确保包含
expires、add_header Cache-Control或proxy_cache相关的配置语法正确、路径可访问; - 检查 location 块是否被更靠前的规则覆盖(比如
location /在前,location ~ \.(js|css)$在后,静态请求根本没进到缓存逻辑); - 用 curl -I http://your.site/style.css 看响应头:若缺少
Cache-Control或Expires,说明缓存指令未生效;若存在但值为no-cache或max-age=0,需检查是否被 upstream 响应头覆盖(Nginx 默认不覆盖后端设置的 Cache-Control)。
定位缓存穿透引发的后端或磁盘压力
当缓存全量失效(如 reload 后、缓存 key 变更、缓存空间满被清空),所有静态请求会打到磁盘或后端,造成 IO 或 CPU 突增:
- 监控 nginx_open_file_cache_hits(启用
open_file_cache时)或 nginx_proxy_cache_hits(启用proxy_cache时):若指标在某时刻归零并缓慢回升,大概率是 reload 或缓存策略重置所致; - 观察 iostat -x 1 中 %util 和 await:若静态资源目录所在磁盘 await 显著升高、%util 接近 100%,说明文件读取成为瓶颈;
- 检查 access_log 中静态请求的
$request_time:若大量 .js/.css 请求耗时从几毫秒跳到 50ms+,且对应$upstream_response_time也同步升高,说明正从磁盘或后端实时读取。
排查因缓存策略不当导致的频繁验证与阻塞
即使缓存未失效,错误的协商缓存配置也会让浏览器反复发 If-Modified-Since 或 If-None-Match 请求,增加 Nginx 和后端的处理负担:
- 确认是否启用了
gzip_static on但对应 .gz 文件缺失:Nginx 会退回到读取原始文件 + 实时压缩,CPU 使用率飙升; - 检查是否对静态资源误配了
etag off或if_modified_since off,导致无法利用协商缓存,每次都要完整响应; - 若使用
proxy_cache,注意proxy_cache_valid 200 302 1h是否覆盖了 304 响应——未配置会导致 304 不进缓存,每次验证都走后端。
结合日志和时间点交叉验证抖动来源
把抖动时间点和缓存相关事件对齐,是最直接的归因方式:
- 查 /var/log/nginx/error.log:是否有
open() "/path/to/file" failed (24: Too many open files)—— open_file_cache 资源耗尽,被迫退化为每次 open/read/close; - 在 access_log 中加
$cache_status字段(如log_format main '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $request_time $upstream_response_time $cache_status';),然后筛选HIT突然变少、MISS或BYPASS集中出现的时间段; - 对比抖动发生前后的 systemctl status nginx 或 journalctl -u nginx --since "2 minutes ago",确认是否恰好有 reload 操作或 worker 进程重启记录。



















