要准确度量特定路径的反向代理缓存命中率,必须将 $upstream_cache_status 真实、干净、可分离地记录进日志,并按路径维度统计六种状态(hit/miss/expired/bypass/stale/updating)占比,而非仅二分;需确保 location 启用 proxy_cache、后端响应头允许缓存、日志格式与 access_log 作用域匹配、避免静态资源误用该变量;为 /api/v2/ 路径单独配置结构化日志与调试头;命中率分母应为六种状态之和;可用 shell 命令快速分析日志分布。

要准确度量特定路径的反向代理缓存命中率,核心是把 $upstream_cache_status 真实、干净、可分离地记录进日志,并按路径维度做状态归类统计——不是只看 HIT/MISS 二分,而是识别六种状态各自占比,才能定位是配置问题、内容问题还是上游干扰。
确保目标路径日志中能稳定输出缓存状态
如果日志里该字段大量为 - 或空,说明状态未被采集。需确认以下四点:
- 对应
location块已启用proxy_cache my_cache(且my_cache在http块中通过proxy_cache_path正确定义) - 后端响应头不含
Cache-Control: no-store、Set-Cookie或Vary: *,否则 Nginx 默认跳过缓存 - 日志格式定义在
http块,且access_log指令写在该location内(作用域必须匹配) - 避免在静态资源
location中误用$upstream_cache_status——它只对proxy_pass生效;纯文件服务应改用$sent_http_x_cache等自定义头
为特定路径单独切分日志并结构化格式
不要把所有流量混在同一个 access.log 里。例如,想分析 /api/v2/ 路径的缓存表现,应在对应 location 中单独配置:
- 在
http块定义统一日志格式:log_format api_cache '$remote_addr [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_cache_status $upstream_response_time $request_time'; - 在
location /api/v2/ { ... }中启用:access_log /var/log/nginx/api_v2_cache.log api_cache; - 同时加调试响应头:
add_header X-Cache-Status $upstream_cache_status;,方便用curl -I快速验证单次行为
按六种状态分类统计,选对分母才反映真实效率
命中率不是 HIT/(HIT+MISS),而应是:
HIT / (HIT + MISS + EXPIRED + BYPASS + STALE + UPDATING)
每种状态含义不同,需分别解读:
- HIT:缓存直接返回,理想状态
-
MISS:首次访问或 key 未命中,若占比高,检查
proxy_cache_key是否含动态变量(如$arg_ts、$cookie_sessionid) -
EXPIRED:缓存存在但过期,说明
proxy_cache_valid设置偏短(API 接口建议至少设200 304 5m) -
BYPASS:被
proxy_cache_bypass规则触发,常见于带Cache-Control: no-cache的请求,需检查前端是否误加头 - STALE:后端不可达时返回旧缓存,属容错机制,但高频出现提示上游不稳定
- UPDATING:缓存正在后台更新,客户端仍收到旧内容,属正常行为
用简单命令快速抓取和对比路径级命中分布
无需部署监控系统,一条 shell 命令就能产出路径级缓存健康快照:
- 统计最近 1000 行中各状态频次:
tail -1000 /var/log/nginx/api_v2_cache.log | awk '{print $NF}' | sort | uniq -c | sort -nr - 过滤出非 HIT 请求并查看典型 URL:
awk '$NF != "HIT" {print $7, $NF}' /var/log/nginx/api_v2_cache.log | head -20 - 对比两个时间段的 HIT 率变化(如发布前后):
awk 'NR>=1000 && NR=1000 && NR











