要实时抓取 upstream_cache_status 指标,需先启用 proxy_cache 并在 access_log 中显式记录该变量,再通过 Loki/ELK 或 nginx-prometheus-exporter 结合日志分析实现缓存命中率等监控。

要实时抓取 upstream_cache_status 指标,关键不是“监控 upstream 的 cache 状态”,而是让 Nginx 把这个变量真实记录下来并暴露给监控系统。因为 $upstream_cache_status 本身只是一个日志变量,不主动上报、不自动导出,必须通过 access log + 日志解析(如 Loki/ELK)或配合 Prometheus exporter 做二次加工才能进入监控体系。
确认 Nginx 缓存配置已启用且变量可用
该变量仅在启用 proxy_cache(或 fastcgi_cache 等)时有效,且只在 proxy_pass 场景下由 Nginx 主动填充。确保以下配置存在:
- 定义了
proxy_cache_path,并指定了keys_zone名称(如my_cache) - 在 location 或 upstream 转发逻辑中启用了缓存:
proxy_cache my_cache; - 未设置
proxy_cache_bypass或proxy_no_cache导致缓存被跳过
将 upstream_cache_status 写入 access log
这是最直接、零依赖的落地方式。Nginx 本身不提供该变量的 Prometheus 原生指标,但可通过自定义日志格式让它持续落盘:
- 在
http块中定义日志格式,显式包含该变量:log_format cache_log '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" $upstream_cache_status $upstream_response_time $request_time'; - 在对应 location 中启用该格式:
access_log /var/log/nginx/cache.log cache_log; - 重启 Nginx 后,每条请求日志末尾会追加类似
HIT、MISS、EXPIRED、BYPASS的状态标识
对接日志分析系统做实时统计
有了结构化日志,就可以用成熟工具做聚合计算(如缓存命中率 = HIT / (HIT + MISS + EXPIRED)):
-
Loki + Grafana:用 LogQL 查询
{job="nginx"} |~ `HIT|MISS|EXPIRED`,再用rate()和count_over_time()计算分钟级命中率 -
Filebeat + Elasticsearch:配置 ingest pipeline 提取
upstream_cache_status字段为 keyword 类型,便于 Kibana 可视化下钻 - 注意避免高频写入导致磁盘压力:可单独切分 cache.log,配合
logrotate控制保留策略
进阶:用 nginx-prometheus-exporter 补充缓存维度指标
虽然 exporter 默认不解析 $upstream_cache_status,但它能采集 proxy_cache_path 对应的磁盘使用率、keys_zone 内存占用、以及通过 stub_status 间接反映缓存效果的全局请求数。可组合使用:
- 开启
stub_status并暴露/nginx_status - 启动 exporter 时指定
--nginx.scrape-uri=http://127.0.0.1/nginx_status - 搭配日志方案,用 PromQL 关联:比如当
nginx_http_requests_total{status=~"2.."} / rate(nginx_http_requests_total[5m])下降,同时日志中MISS比例上升,即可定位缓存失效问题
不复杂但容易忽略:这个变量只在缓存生效路径中产生意义,如果 upstream 返回了 Cache-Control: no-store 或 Nginx 配置了 proxy_ignore_headers Cache-Control,它也可能恒为 BYPASS——得结合响应头和配置双向验证。











