Nginx 缓存命中率监控:从 X-Cache-Status 到实时统计

背景

上一篇配好了 Nginx 缓存,响应头里加了 X-Cache-Status,浏览器 F12 里能看到 HIT 和 MISS。

但问题来了:每次都要手动 F12,看不到整体情况。

想知道:

今天的缓存命中率是多少?

哪些请求总是 MISS?

缓存到底省了多少后端压力?

需要把 X-Cache-Status 从"单个请求可见"变成"可统计"。

原因

默认情况下,Nginx 的 $upstream_cache_status 只是一个响应头------它跟着响应发给浏览器,但不进日志。

要统计,得做两件事:

把这个变量写进 Nginx 的 access log

用脚本统计日志里的 HIT/MISS 数量

解决

第一步:定义带缓存状态的日志格式

编辑 Nginx 主配置:

bash 复制代码
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 配置里启用新日志

css 复制代码
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;
    }
}

检查 + 重启:

bash 复制代码
sudo nginx -t
sudo systemctl reload nginx

第三步:验证日志有内容

bash 复制代码
# 访问几次网站
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 ------ 缓存的加速效果一目了然。

第四步:写统计脚本

bash 复制代码
#!/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 "================================"

运行:

bash 复制代码
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:

bash 复制代码
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 的平均耗时对比

bash 复制代码
# MISS 的平均耗时
sudo grep "Cache: MISS" /var/log/nginx/cache.log | \
  awk '{print $NF}' | awk -F: '{sum+=$2; n++} END {print sum/n}'
相关推荐
Decay__11 小时前
05_MySQL 常用 SQL 大全 —— 诊断、管理、优化辅助 SQL 与三大系统库速查
运维·数据库·sql·mysql·架构
贞明电子13 小时前
工业三色报警灯怎么接入项目系统?开关量与RS485控制应用指南
运维·网络·微信公众平台·贞明电子
万联WANFLOW13 小时前
海外网络故障怎么排查?Cloudflare 三季度断网报告解读与 mtr 实战
运维·网络·故障分析
Ruiery15 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
Decay__16 小时前
04_MySQL DBA 日常运维手册 —— 会话管理、锁与阻塞、事务监控、慢查询与日志巡检
运维·数据库·sql·mysql·架构
江华森18 小时前
数据中心基础设施运维实战:概述与实验环境搭建
运维
迪菲赫尔曼18 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
一枕槐安48719 小时前
RAG 服务扛住高并发:缓存、队列、限流三件套
java·spring·缓存·异步任务·rag·断路器
by2099919 小时前
Linux GCC/G++ 编译与 Makefile 构建
linux·运维·服务器·经验分享
螺丝钉tina20 小时前
[Playwright][08] Upload 模块自动化:如何设计真实业务测试用例?
运维·自动化·测试用例