nginx可通过map+条件日志精准采集目标url访问数据,结合awk按小时聚合生成热度快照并写入hotmap.map,再用$hot_level驱动缓存、限流等策略;支持lua共享字典实现毫秒级实时计数。

监控特定 URL 路径的访问热度与频率,核心是“精准采集 + 低开销聚合 + 可驱动策略”。Nginx 本身不直接提供热力图或实时排行榜,但通过内置变量、条件日志、共享内存和轻量外部分析,能稳定支撑生产级 URL 级监控。
用 map + 条件 access_log 只记录目标路径
避免全量日志污染,大幅降低磁盘与解析压力:
- 在 http 块中定义匹配规则,例如只关注 /api/v2/order/create 和 /api/v2/user/profile:
map $request_uri $is_target_url {
~^/api/v2/order/create 1;
~^/api/v2/user/profile 1;
default 0;
}
- 定义专用日志格式,含时间、URI、状态码、响应体大小和耗时:
log_format target_log '$time_iso8601 $uri $status $body_bytes_sent $request_time';
access_log /var/log/nginx/target_access.log target_log if=$is_target_url;
- 该配置让 Nginx 内核层完成过滤,只有命中路径才写日志,无需后续 grep 或正则扫描。
按小时聚合生成热度快照
热度本质是单位时间内的请求密度,按小时统计比秒级更稳、资源消耗更低:
- 用一行 awk 统计最近一小时最热的 20 个 URI:
awk -v cutoff="$(date -d '1 hour ago' +'%Y-%m-%d %H:%M:%S')" '$1 > cutoff {print $2}' /var/log/nginx/target_access.log | sort | uniq -c | sort -nr | head -20
- 将结果定期(如每小时 cron)写入 /etc/nginx/conf.d/hotmap.map,用于后续策略映射;
- 示例内容:
map $uri $hot_level {
default "cold";
"~^/api/v2/order/create$" "hot";
"~^/api/v2/user/profile$" "warm";
}
用 $hot_level 驱动差异化行为
让热度数据真正影响服务,不止于报表:
- 在对应 location 中引用变量控制缓存或限流:
location ~ ^/api/v2/ {
expires 1s; # 默认不缓存
add_header X-URL-Hotness $hot_level;
if ($hot_level = "hot") {
limit_req zone=api_hot burst=30 nodelay;
expires 5s;
}
}
- 也可配合 proxy_cache_valid 设置不同过期时间,或用 log_by_lua 上报到 Redis 实时计数;
- 每次更新 hotmap.map 后执行 nginx -t && nginx -s reload 即可生效。
补充:单机轻量实时计数(需 Lua 支持)
若需毫秒级响应(如防刷联动),可用 shared dict:
- 在 http 块中声明共享字典:
lua_shared_dict url_counter 10m; - 在 location 中用 access_by_lua_block 计数:
access_by_lua_block {
local dict = ngx.shared.url_counter;
local key = ngx.var.uri;
dict:incr(key, 1);
} - 再用 log_by_lua_block 写入指标或触发阈值动作,适合小规模高敏场景。











