nginx代理缓存命中率需通过$upstream_cache_status变量配合日志与脚本统计,其值含hit、miss等状态;用awk实时计算hit占比,并区分bypass等非缓存流程;长期监控可接入prometheus或定时脚本记录趋势。

要监控 Nginx 代理缓存(即 proxy_cache)的命中率,核心不是监控“缓冲区”本身,而是监控缓存行为是否生效、请求是否真正命中缓存。Nginx 没有直接暴露“代理缓冲区命中率”的指标,但通过标准配置 + 日志 + 状态变量,可以精准、低成本地实现命中率统计与分析。
下面分三步讲清楚怎么做:
配置关键变量:让每次响应携带缓存状态
在你要缓存的 location 块中,添加响应头和日志变量:
location ~* \.(js|css|png|jpg|gif|woff2|svg)$ {
proxy_cache my_cache;
proxy_cache_valid 200 304 1y;
proxy_cache_key "$scheme$host$request_uri";
# 关键:把缓存执行结果透出到响应头,便于浏览器或脚本验证
add_header X-Cache-Status $upstream_cache_status;
# 关键:把状态写入访问日志,用于批量分析
access_log /var/log/nginx/static-access.log cache_log;
}
同时,在 http 块顶部定义日志格式(确保 $upstream_cache_status 可用):
log_format cache_log '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" $upstream_cache_status';
✅
$upstream_cache_status是唯一权威缓存状态变量,值包括:HIT、MISS、EXPIRED、BYPASS、STALE、REVALIDATED等。
实时统计命中率:用命令快速算出百分比
假设日志路径是 /var/log/nginx/static-access.log,运行以下命令即可查看当前命中率(HIT 占比):
# 总请求数 & HIT 数(忽略空行和注释)
awk '$12 != "-" && $12 != "" {total++; if($12 == "HIT") hit++} END{printf "HIT Rate: %.2f%% (%d/%d)\n", hit/total*100, hit, total}' /var/log/nginx/static-access.log
想看各状态分布:
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
awk '{print $12}' /var/log/nginx/static-access.log | sort | uniq -c | sort -nr
常见输出示例:
8423 HIT
1567 MISS
302 EXPIRED
98 BYPASS
⚠️ 注意:
BYPASS表示请求被规则跳过(如带 Cookie、非 GET 方法、含Cache-Control: no-cache),它不算“缓存失败”,而是“根本没进缓存流程”,需单独排查。
长期可观测:接入 Prometheus 或定时脚本
若需图表化、告警或趋势分析,推荐两种轻量方式:
-
方式一:用
stub_status+ 自定义 exporter
启用 Nginx 状态页(仅限内网):location /nginx_status { stub_status on; access_log off; allow 127.0.0.1; deny all; }再配合 nginx-prometheus-exporter 抓取
nginx_http_request_cache_status_total指标(需 Nginx ≥ 1.17 + 启用--with-http_stub_status_module)。 -
方式二:每分钟跑一次 awk 脚本写入文件
#!/bin/bash LOG="/var/log/nginx/static-access.log" NOW=$(date +%s) HIT=$(awk '$12=="HIT"{h++} END{print h+0}' $LOG) TOTAL=$(wc -l > /var/log/nginx/cache-rate.log后续可用 Grafana 或简单
gnuplot绘图。
不复杂但容易忽略










