最轻量可靠的方式是通过Nginx自定义日志格式记录缓存状态,核心使用$upstream_cache_status变量标识HIT、MISS等缓存行为,并为静态资源路径单独配置access_log以精准统计命中率。

直接通过 Nginx 自定义日志格式记录缓存状态,是最轻量、最可靠的方式监控静态资源缓存命中率。关键在于使用 $upstream_cache_status 变量——它会在每次请求结束时,明确标记该次响应是否来自缓存,以及具体是哪种缓存行为。
启用并配置 cache_status 日志字段
在 http 块中定义一个带缓存状态的日志格式:
log_format cache_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'Cache: $upstream_cache_status '
'Upstream: $upstream_addr ';然后在 server 或 location 中启用该日志(建议单独为静态资源路径设置):
location ~* \.(jpg|jpeg|png|gif|css|js|woff2?|ttf|eot|svg)$ {
access_log /var/log/nginx/static_cache.log cache_log;
# 其他静态资源配置(如 expires、sendfile 等)
}$upstream_cache_status 的典型取值包括:
- HIT:缓存命中,直接返回本地缓存内容
- MISS:缓存未命中,回源获取并写入缓存
-
EXPIRED:缓存存在但已过期,回源验证(若启用
proxy_cache_revalidate) -
STALE:返回过期缓存(因后端不可用或启用
proxy_cache_use_stale) -
BYPASS:被
proxy_cache_bypass规则跳过缓存 -
UPDATING:缓存正在更新,返回旧版本(配合
proxy_cache_use_stale updating)
区分静态资源与代理缓存场景
注意:$upstream_cache_status 仅在启用 proxy_cache 时有效(即 Nginx 作为反向代理时)。如果你的静态资源是直接由 Nginx root 或 alias 提供(非 proxy_pass),该变量恒为空或 -,无法反映浏览器缓存行为。
此时应改用客户端视角的缓存控制头分析,例如:
log_format client_cache '$remote_addr [$time_local] '
'"$request" $status '
'Cache-Control: "$sent_http_cache_control" '
'Expires: "$sent_http_expires"';再配合 expires 和 add_header Cache-Control 配置,可间接判断是否按预期设置了强缓存。
快速统计命中率(命令行实操)
日志就位后,用一行 shell 命令即可算出近一小时 HIT 占比:
awk '$12 ~ /^HIT$/ {hit++} $12 ~ /^(MISS|EXPIRED|STALE|UPDATING)$/ {total++} END {printf "Hit Rate: %.2f%\n", hit/total*100}' /var/log/nginx/static_cache.log说明:$12 是上面 cache_log 格式中 Cache: 后的第 12 个字段(请根据实际字段位置调整)。也可用 grep -c "Cache: HIT" 配合总请求数做简单估算。
补充建议:避免日志干扰,精准聚焦静态资源
为防止日志混杂、统计失真,推荐:
- 为静态资源 location 单独指定
access_log,不复用全局日志 - 关闭非必要日志项(如
access_log off在非静态 location 中) - 结合
map指令过滤掉调试请求或爬虫(如 User-Agent 包含HeadlessChrome) - 定期轮转日志(
logrotate),防止单文件过大影响分析效率


















