直接通过日志中 $upstream_cache_status 状态可快速定位缓存是否生效及未命中原因:需在 http 块定义含该变量的日志格式,location 中启用 proxy_cache 和 access_log,并用 tail/awk 统计 HIT/MISS/EXPIRED/BYPASS/STALE 等状态分布,结合 proxy_cache_key 优化与 proxy_cache_valid 分层设置提升命中率。

直接看日志里的 $upstream_cache_status,就能快速定位缓存是否生效、为什么没命中——这是调优静态资源缓存命中率最轻量也最有效的方式。
把缓存状态真实写进日志
只启用 proxy_cache 不够,必须让每次请求的缓存行为“可被看见”。在 http 块中定义日志格式,明确包含该变量:
- 确保 location 中已配置 proxy_cache 和 proxy_cache_valid
- 添加日志格式(例如):
log_format cache_log '$remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_cache_status $upstream_response_time $request_time'; - 在静态资源 location(如 /static/ 或 \.(js|css|png|jpg)$)中启用:
access_log /var/log/nginx/static_cache.log cache_log; - 注意:$upstream_cache_status 仅在使用 proxy_pass + proxy_cache 时有效;若用 fastcgi_cache,请换为 $fastcgi_cache_status
从日志高频状态反推问题根因
滚动查看日志或用 tail -f /var/log/nginx/static_cache.log | awk '{print $NF}' | sort | uniq -c | sort -nr 统计末尾字段,重点关注以下状态含义:
- HIT:缓存命中最理想状态,但比例过高也可能说明内容未及时更新(需核对 proxy_cache_valid 是否过长)
- MISS:首次访问或缓存未生成。检查是否因 proxy_cache_key 过细(如含 $cookie_sessionid、$arg_ts、$http_user_agent)导致同一资源生成多个 key
- EXPIRED:缓存存在但已过期。说明 proxy_cache_valid 设置偏短,尤其对 JS/CSS/图片建议设为 200 304 7d
- BYPASS:请求被显式绕过缓存(如带 no-cache 头、或配置了 proxy_cache_bypass)。检查是否前端误加了 Cache-Control: no-cache
- STALE:缓存已过期但仍在返回(因启用了 proxy_cache_use_stale)。属容错设计,非异常,但大量出现可能反映后端不稳定
精简缓存键与延长有效期是见效最快的两步
命中率长期低于 70%,大概率卡在这两个配置上:
- 重设 proxy_cache_key:默认值含 $args,极易因 utm_ 参数、时间戳等造成碎片化。推荐改为
proxy_cache_key $scheme$host$request_uri; —— 忽略参数和大小写差异 - 按资源类型分层设置 proxy_cache_valid:
• 图片/字体:200 304 30d
• JS/CSS:200 304 7d
• HTML(若静态):200 304 1h(避免长期 stale) - 加一层保险:proxy_cache_lock on 防止缓存失效瞬间多个请求同时回源;use_temp_path off 减少磁盘写开销
配合响应头辅助验证缓存行为
日志只是记录,加一个响应头能让调试更直观:
- 在 location 中添加:
add_header X-Cache-Status $upstream_cache_status; - 用 curl -I 请求任意静态资源,直接看到返回头中的状态,比翻日志更快定位单次请求行为
- 注意:该头不替代日志统计,仅用于人工验证;生产环境可酌情关闭以减少响应体积


















