背景 上一篇配好了 Nginx 缓存,响应头里加了 X-Cache-Status,浏览器 F12 里能看到 HIT 和 MISS。
但问题来了:每次都要手动 F12,看不到整体情况。
想知道:
今天的缓存命中率是多少?
哪些请求总是 MISS?
缓存到底省了多少后端压力?
需要把 X-Cache-Status 从"单个请求可见"变成"可统计"。
原因 默认情况下,Nginx 的 $upstream_cache_status 只是一个响应头——它跟着响应发给浏览器,但不进日志。
要统计,得做两件事:
把这个变量写进 Nginx 的 access log
用脚本统计日志里的 HIT/MISS 数量
解决 第一步:定义带缓存状态的日志格式 编辑 Nginx 主配置:
sudo nano /etc/nginx/nginx.conf
在 http 块里找到 log_format 那一行,新增一个格式:
log_format cache_log '$remote_addr - [$time_local] '
'"$request" $status '
'Cache: $upstream_cache_status '
'Time: $request_time';
含义:
$upstream_cache_status → 就是 HIT / MISS / BYPASS
$request_time → 请求耗时,看缓存有没有真的加速
第二步:在 dashboard 配置里启用新日志
server {
listen 8081;
access_log /var/log/nginx/cache.log cache_log; # 启用新日志格式
location / {
proxy_cache my_cache;
add_header X-Cache-Status $upstream_cache_status;
proxy_pass http://dashboard_cluster;
}
}
检查 + 重启:
sudo nginx -t
sudo systemctl reload nginx
第三步:验证日志有内容
# 访问几次网站
curl -sI http://127.0.0.1:8081 > /dev/null
curl -sI http://127.0.0.1:8081 > /dev/null
# 看日志
sudo tail -5 /var/log/nginx/cache.log
预期输出:
192.168.1.1 - [06/Oct/2026:15:30:12 +0800] "GET / HTTP/1.1" 200 Cache: MISS Time: 0.025
192.168.1.1 - [06/Oct/2026:15:30:13 +0800] "GET / HTTP/1.1" 200 Cache: HIT Time: 0.001
Time 那一列:HIT 的耗时是 MISS 的 1/20 —— 缓存的加速效果一目了然。 第四步:写统计脚本
#!/bin/bash
# cache-stats.sh
LOG="/var/log/nginx/cache.log"
TOTAL=$(sudo grep -c "Cache:" "$LOG")
HIT=$(sudo grep -c "Cache: HIT" "$LOG")
MISS=$(sudo grep -c "Cache: MISS" "$LOG")
BYPASS=$(sudo grep -c "Cache: BYPASS" "$LOG")
if [ "$TOTAL" -eq 0 ]; then
echo "日志为空"
exit 0
fi
RATE=$(awk "BEGIN {printf \"%.1f\", $HIT / $TOTAL * 100}")
echo "================================"
echo " 缓存命中率统计"
echo "================================"
echo "总请求: $TOTAL"
echo "HIT: $HIT"
echo "MISS: $MISS"
echo "BYPASS: $BYPASS"
echo "命中率: $RATE%"
echo "================================"
运行:
chmod +x cache-stats.sh
./cache-stats.sh
预期输出:
================================
缓存命中率统计
================================
总请求: 1250
HIT: 1032
MISS: 218
BYPASS: 0
命中率: 82.6%
================================
第五步:加到定时任务
crontab -e
每天 8 点输出一次统计,追加到日志:
0 8 * * * /home/YOUR_USER/cache-stats.sh >> /home/YOUR_USER/cache-stats.log 2>&1
三个坑 坑 1:忘了在 server 块里启用新日志格式
只在 http 里定义了 log_format 不够,每个 server 块要显式指定 access_log ... cache_log。不写,默认还是走 combined 格式,里面没有缓存状态。
坑 2:日志无限增长
加了新日志后,/var/log/nginx/cache.log 会一直涨。要配 logrotate:
sudo nano /etc/logrotate.d/nginx-cache
写入:
/var/log/nginx/cache.log {
daily
rotate 7
compress
missingok
notifempty
}
不配的话,跑几个月日志能到几十 GB。
坑 3:只看命中率不看时间
命中率 80% 听起来不错,但如果 MISS 的都是慢请求,用户体验还是很差。
要看两个维度:
命中率(HIT / TOTAL)
HIT 和 MISS 的平均耗时对比
# MISS 的平均耗时
sudo grep "Cache: MISS" /var/log/nginx/cache.log | \
awk '{print $NF}' | awk -F: '{sum+=$2; n++} END {print sum/n}'