nginx可通过日志分析、map映射、proxy_cache_min_uses和多级cache_path实现url热度分级管理:用access_log统计频次,map映射cache_ttl,min_uses控制缓存写入门槛,不同inactive时间隔离冷热资源,并结合stub_status与prometheus调优命中率。

Nginx 本身不内置“热度感知”能力,但可以通过组合日志分析、动态映射和缓存淘汰机制,为不同 URL 实现差异化的热度管理。核心不是让 Nginx 自动判断冷热,而是用外部信号驱动内部策略——把热度变成可配置的参数。
用日志统计 + map 映射实现 URL 级热度分级
热度本质是访问频次与时间窗口的函数。Nginx 的 access_log 是最直接的数据源:
- 定义专用日志格式,突出 URI 和时间戳:
log_format hotlog '$time_iso8601 $uri $status $request_time'; - 对静态资源 location 单独启用该日志:
access_log /var/log/nginx/hot.log hotlog; - 每小时跑一次统计脚本(如用 awk + sort -nr),取前 10% 的 URI 标记为“热”,中间 70% 为“温”,后 20% 为“冷”
- 生成
/etc/nginx/conf.d/heat.map,内容类似:map $uri $cache_ttl {<br> default "10m";<br> "~^/static/js/app\..*\.js$" "1d";<br> "~^/api/product/\d+$" "30m";<br> "~^/static/img/avatar/" "1h";<br> } - 在 location 中引用:
expires $cache_ttl;或proxy_cache_valid 200 $cache_ttl;
用 proxy_cache_min_uses 控制写入门槛
避免低频请求“占坑”,只让真正有复用价值的响应进缓存:
-
proxy_cache_min_uses 2;表示同一 URI 至少被请求 2 次,才会写入缓存(首次仍会回源) - 它不影响查找——若缓存已存在且未过期,第 1 次请求仍可命中;只是不把这次响应存进去
- 搭配
proxy_cache_lock on;更稳妥:首个请求回源时,后续同 URI 请求排队等待,等缓存写入后统一返回,自然满足 min_uses 条件 - 建议按 location 分层设置:JS/CSS 设为 2,用户资料页设为 2~3,后台接口或带敏感参数的路径设为 off 或 5+(视业务而定)
用 inactive + 缓存区隔离自动清理冷资源
不靠人工标记,靠访问活跃度自动释放空间:
- 为不同热度级别分配独立缓存区:
proxy_cache_path /data/nginx/hot levels=1:2 keys_zone=hot:50m max_size=2g inactive=2h;<br> proxy_cache_path /data/nginx/warm levels=1:2 keys_zone=warm:30m max_size=1g inactive=30m;<br> proxy_cache_path /data/nginx/cold levels=1:2 keys_zone=cold:10m max_size=500m inactive=5m;
- 在对应 location 中绑定:
location ~* \.(js|css)$ { proxy_cache hot; ... }location ~ ^/api/user/ { proxy_cache warm; ... }location ~ ^/legacy/ { proxy_cache cold; ... } - inactive 时间越短,冷资源淘汰越快——5 分钟无访问即清理,不占用磁盘也不干扰热区
用 stub_status + Prometheus 辅助人工调优
实时指标不能替代热度建模,但能验证策略效果:
- 开启
stub_status并暴露给监控工具,重点关注:nginx_cache_hits、nginx_cache_misses、nginx_cache_expired - 结合日志导出器(如 prometheus-nginxlog-exporter),计算各 URI 的 5 分钟命中率趋势
- 当某类 URL 命中率持续低于 30%,说明当前
cache_ttl或min_uses设置偏高,需下调;若命中率超 95% 且inactive频繁触发清理,则可适当延长过期时间或扩大缓存区











