Margrop
Articles374
Tags738
Categories7

Categories

/v1/models 0.025s 0步 0步元递归 0步本身 12类 192.168.x.x 1password 22类一键汇总 3层定位法 401 4个Gateway 4个Gateway全军覆没 503 60秒延迟 60秒超时 6个节点 AC ACP AI AI Coding Assistant AI编程助手 AI辅助 AI辅助编程 AP API Agent couldn't generate Alertmanager AppDaemon Aqara BaiduPCS CC-Switch CI/CD CLI Tools CLI工具 CONFIG Caddy Chrome缺失 Claude Code Cloudflare Codex Cookie 认证 Cron D1 DB探针 DB静止 DIY-123模型 DIY-MINI DIY平台 Date Diagrams.net Diary Docker Docker Compose EADDRINUSE EasyTier NAT穿透 Efficiency Tools Electerm English FTS5 Gateway Gemini CLI GitHub Actions HA HADashboard Hermes Hexo HomeAssistant IP IPv4 Java LVM‑Thin Linux MacOS Macmini Macmini log路径 Markdown MiniMax MiniMax-M3 Multi-Agent MySQL NAS NRestarts Nginx Node-RED Node.js OOM OpenAI OpenClaw OpenClaw gateway OpenCode OpenResty OpenWrt PPPoE Portainer PostgreSQL ProcessOn Prometheus Proxmox VE RPC Restart=always Restart=always循环 SOCKS5 SQLite SSL Session Shell Subagent TTS TimeMachine UML Uptime Kuma VM151 VM152 WeCom缺失 VM153 VPN VPS VPS4 VPS4 overlay TCP不可达 WeCom Web WebSocket Windows Workers activate ad adb adblock agent aligenie aliyun alpine annotation aop authy auto-restart autofs backup baidupan bash bitwarden boot brew browser by-design caddy2 capture_output cdn centos cert certbot charles chat chat completion chrome classloader client clone closures cloudflare cmd command commit connected container cron crontab cron任务 cron设计 ctyun dashboard ddsm demo dependency deploy developer devtools dll dns docker domain download draw drawio dsm dump duplicate service unit dylib edge exception exit 78 export fail2ban fallback fallback失效 feign firewall-cmd flow frp frpc frps fuckgfw function fuser gcc gfw git gitea github golang google_gemma-4 gperftools gridea grub gvt-g hacs havcs heap hello hexo hibernate hidpi hoisting homeassistant hosts html htmlparser https iKuai idea image img img2kvm immortalwrt import index install intel io ios ip iptables iptv ipv6 iso java javascript jetbrains jieba jni jnilib journald journald日志漂移 jpa js json jsonb jupter jupyterlab jvm k8s kernel key kid kms kodi koolproxy koolproxyr kvm lan lastpass launchctl learning lede letsencrypt linux live loopback-proxy low-code lsof lvm lxc m3u8 mac macos manual mariadb markdown maven md5 meta-acceptance meta-pattern meta-probe microcode mirror model provider modem modules monitor mount mstsc mysql n2n n5105 nas netstat network new-api nfs node node-red nodejs nohup notepad++ npm nssm ntp one-api oop openfeign openssl os otp ovz p14 packet capture pat pdf pem perf ping ping通但chat不通 pip plugin png port=18789 powerbutton print pro proxy pve pvekclean python qcow2 qemu qemu-guest-agent rar reboot reconnect循环 reflog remote remote desktop renew repo resize retina root route router rule rules running runtime safari sata schema schema列名 scipy-notebook scoping scp server server is busy service不可信 slmgr so socket-proxyd socks source spk split边界 spring springboot springfox sqlite3 CLI ss ssh ssl stale stash stderr被吞 string subprocess supernode svg svn swagger sync synology system-level daemon system-level vs user-level system-level与user-level抢端口 systemctl systemctl disable systemd systemd duplicate service systemd exit 78 systemd service unit systemd unit systemd unit race systemd-socket systemd被覆盖 tap tap-windows tapwindows telecom template terminal tls tmux token token失效 totp transient 999 trigram tvbox txt ubuntu udisk ui undertow unicode61 uninstall unlocker upgrade upstream provider timeout uptimeMs url user-level daemon v10探针 v11探针 v12探针 v13探针 v1探针 v2ray v6探针 v7探针 v8探针 vhd vim vlmcsd vm vmdk web websocket wechat windows with work day 2 worker wow xiaoya xml yum zip 一键告警脚本 上游LLM容量 不是我的锅 中国电信 中文搜索 主动0步 主动0步本身 主动不追问 主动不追问本身 主动不追问本身也是清单之外 主动不通知 主动不通知本身 主动修 主动修system-level本身也是清单之外 主动修本身也是清单之外 主动周一 主动意识到 主动意识到0步本身 主动意识到0步本身也是清单之外 主动追问 云电脑 交换机 人机协作 代理 优化 但chat 30s+ 但是我的事 体检 保护逻辑本身也是清单之外 修挖坑闭环 修正本身 修正递归 值班 假阳 假阴 健康检查 元递归 光猫 全绿 全量同步 公网IP 内存 内存优化 内网 内网IP 内网渗透 写作 分词 切换 列名误判 升级 协作 单位混淆 博客 反向代理 反常稳定 反应 vs 知识 启动 告警 告警优化 周一 周一焦虑 周三 周二 周二晚上 周五 周六 周四 周报 周日 周末 周末也是清单之外 周末本身也是清单之外 周末突破 周末第二天 周末落地 周末落地本身 夏令时 多场景 多智能体 多节点 多节点管理 天猫精灵 天翼云 安全 安装 定时任务 容器 容器网络 导入 小米 工作感悟 工作日 工作日常 工作日第三天 工作日第五天 工作日第四天 已通知用户 常用软件 幂等 广告屏蔽 序列号 应用市场 异常 循环类 心态 心智成长 心理模型 心跳 心跳检查 性能优化 感悟 打工 打工人 打工人的无奈 批量校验 技术 抓包 挖坑→修坑闭环 排查 排查思路 探针再升级 探针本身 探针版本 探针管理 探针自检 探针踩坑 接受 接受之后 接受修 接受修正 接受层 接受挖坑 接受本身 接受递归 描述文件 放下 故障 故障排查 效率 效率工具 数据 旁路由 旁路进程 无服务器 日记 时区 显卡虚拟化 智能家居 智能音箱 服务器 服务管理 架构 梯子 模块 模型别名映射 模型探测 模型端点可达性 模型端点能ping通 模型调用 毫秒 流程 流程图 流程管理 浏览器 清单之后 清单之外 清单之外也包括接受本身 清单的元递归 清单设计 清单边界 清单进化 源码备份 漫游 激活 激活循环 火绒 焦虑 玄学 生活 电信 画图 监控 监控系统 直播源 直觉 磁盘 端口 端口冲突 端口扫描 第10天 第10类 第11天 第11类 第12天 第12类 第13天 第13类 第14天 第14类 第15类 第16天 第16类 第17类 第18类 第19类 第20类 第21类 第22类 第23类 第25类 第6天 第7天 第8天 第9天 第9类 管理 续期 网关 网络 网络风暴 群晖 脚本 脚本优化 腾讯 自动化 自动恢复 自建应用 自我反思 自我打脸 节点角色 虚拟机 被动意识到 角色不匹配 角色误判 角色误配 角色错配 认证 设计偏差 证书 语雀 误报 误报过滤 超时 路由 路由器 软件管家 软路由 运维 运维监控 进程 连接保活 连接问题 通信机制 通知 通知元递归 通知挖坑 通知本身 部署 部署链路 配置 配置落后 钉钉 镜像 镜像源 长期稳定 长连接 门窗传感器 问题排查 防火墙 阿里云 阿里源 集客 静默期 飞书

Hitokoto

Archive

Prometheus 抓取间隔设置与告警延迟优化:如何平衡资源消耗与监控实时性

Prometheus 抓取间隔设置与告警延迟优化:如何平衡资源消耗与监控实时性

前言

监控系统是运维工作的眼睛。如果监控不给力,就像在黑暗里走路——你不知道哪里会踩坑,什么时候会掉队。

Prometheus 是目前最流行的开源监控方案之一,很多公司都在用。但在实际使用中,有一个问题经常被忽视:抓取间隔(scrape_interval)应该设置多少合适?

抓取间隔太短,Prometheus 压力太大,资源消耗严重。
抓取间隔太长,告警延迟太高,问题发现不及时。

本文将详细讨论 Prometheus 抓取间隔的设置原则,以及如何根据不同场景优化告警延迟。

问题背景

典型的监控架构

在一个典型的微服务架构中,监控系统通常是这样的:

1
2
3
4
[应用服务] --> [Prometheus 抓取] --> [时序数据库] --> [Grafana 可视化]
|
v
[AlertManager] --> [告警通知]

Prometheus 定期从各个目标服务抓取指标,存入自己的时序数据库。然后根据配置好的告警规则,检测是否需要触发告警。

这里有几个关键参数:

  1. scrape_interval:抓取间隔,默认 15 秒
  2. evaluation_interval:告警规则评估间隔,默认 15 秒
  3. scrape_timeout:抓取超时时间,默认 10 秒

监控的”不可能三角”

在监控系统中,存在一个”不可能三角”:

1
2
3
4
5
6
      实时性
/\
/ \
/ \
/______\
成本低 准确率高
  • 实时性高 + 准确率高 = 资源消耗大
  • 实时性高 + 资源消耗少 = 准确率低
  • 资源消耗少 + 准确率高 = 实时性低

没有完美的方案,只有适合的权衡。

抓取间隔的设置原则

默认值 15s 够用吗?

对于大多数场景,15 秒的抓取间隔是够用的。

15 秒意味着每分钟有 4 个数据点,对于大部分指标来说已经足够观察趋势了。而且 15 秒的间隔对被监控服务的影响也比较小。

但有些场景,15 秒可能不够:

  1. 快速变化的核心指标:比如 QPS、延迟分布,需要更细的粒度
  2. 需要快速发现问题的业务:比如支付链路、订单系统
  3. 对延迟敏感的场景:比如实时大屏、SLA 监控

抓取间隔设置参考

根据实际经验,给出以下参考:

场景 建议间隔 说明
普通业务服务 15s 默认够用
核心业务/关键路径 5s-10s 更快的发现问题
基础设施/系统指标 30s-60s 变化慢,不需要太频繁
测试/开发环境 60s+ 降低资源消耗
高频交易/实时系统 1s-5s 几乎实时监控

分层监控策略

更好的做法是采用分层监控策略

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
第一层:基础设施监控(间隔 60s)
- CPU、内存、磁盘、网络
- 变化慢,不需要频繁抓取

第二层:服务健康监控(间隔 15s)
- 服务存活、请求成功率
- 常规告警使用这个层

第三层:业务指标监控(间隔 5s-15s)
- QPS、延迟、错误率
- 关键业务使用这个层

第四层:核心链路监控(间隔 1s-5s)
- 支付、订单等核心链路
- 最高优先级,最短间隔

这种分层策略的好处是:资源消耗与业务重要性匹配,既保证了关键业务的监控质量,又不会给系统带来过大压力。

告警延迟的优化

告警延迟是怎么产生的?

告警从发生到收到通知,延迟主要来自以下几个环节:

1
2
问题发生 --> 等待抓取 --> Prometheus 评估 --> Alertmanager 发送 --> 收到通知
(max scrape_interval) (evaluation_interval)

假设配置是 scrape_interval=15s,evaluation_interval=15s:

  • 最坏情况下,延迟可能是 15s + 15s = 30s
  • 平均延迟大概是 15s + 15s / 2 = 22.5s

如果改成 scrape_interval=5s,evaluation_interval=5s:

  • 最坏情况下,延迟变成 5s + 5s = 10s
  • 平均延迟变成 5s + 5s / 2 = 7.5s

所以,想降低告警延迟,最直接的办法就是缩短抓取间隔和评估间隔

评估间隔的调整

evaluation_interval 控制 Prometheus 多久评估一次告警规则。

1
2
3
4
# prometheus.yml
global:
scrape_interval: 15s # 抓取间隔
evaluation_interval: 15s # 告警规则评估间隔

注意:evaluation_interval 应该跟 scrape_interval 保持一致,或者略大于 scrape_interval。如果你抓取间隔是 5s,评估间隔是 60s,那告警延迟至少是 60s,这就失去实时性了。

告警规则本身的优化

除了调整抓取间隔,告警规则本身的写法也会影响延迟。

不好的写法:

1
2
3
4
5
6
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m])) > 0.05
for: 0m

这个规则使用了 5 分钟的 rate 查询,天然就有 5 分钟的”预热”时间,告警会滞后至少 5 分钟。

优化的写法:

1
2
3
4
5
6
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[1m]))
/
sum(rate(http_requests_total[1m])) > 0.05
for: 1m

[5m] 改成 [1m],预热时间从 5 分钟降到 1 分钟。

使用 recording rules 减少计算延迟

对于复杂的告警规则,可以使用 recording rules 预计算:

1
2
3
4
5
6
7
8
9
10
11
# 预先计算好错误率
- record: job:http_error_rate:1m
expr: |
sum(rate(http_requests_total{status=~"5.."}[1m]))
/
sum(rate(http_requests_total[1m]))

# 告警规则使用预计算结果
- alert: HighErrorRate
expr: job:http_error_rate:1m > 0.05
for: 1m

这样做的好处是:

  1. 告警评估时不需要再计算复杂的 rate 表达式
  2. 减少了 Prometheus 的计算压力
  3. 可以使用更短的 rate 窗口(如 30s),进一步降低延迟

资源消耗的权衡

抓取间隔与资源消耗

抓取间隔越短,Prometheus 需要处理的指标数据越多,资源消耗越大。

具体影响:

抓取间隔 指标数量(假设 100 个目标) 存储增长 CPU 消耗
15s ~500,000 个时序 基准 基准
5s ~1,500,000 个时序 3x ~2.5x
1s ~7,500,000 个时序 15x ~10x

可以看到,1s 抓取的资源消耗是 15s 的 10 倍以上,需要谨慎使用。

合理的采样策略

对于不需要高频监控的指标,可以使用合理的采样策略:

1
2
3
4
5
6
7
8
9
10
11
# 对于 CPU、内存等缓慢变化的指标,抓取间隔可以设长一些
- job_name: 'node'
scrape_interval: 60s
static_configs:
- targets: ['localhost:9100']

# 对于 QPS、延迟等需要细粒度的指标,抓取间隔设短一些
- job_name: 'api'
scrape_interval: 5s
static_configs:
- targets: ['localhost:8080']

标签基数控制

抓取间隔只是资源消耗的一个方面。标签基数(label cardinality)也会严重影响 Prometheus 的性能和存储。

1
2
3
4
5
6
7
8
9
10
# 不好的写法:标签值太多
- job_name: 'request'
metrics_path: /metrics
static_configs:
- targets: ['localhost:8080']
labels:
service: api
method: GET
path: /users/{user_id} # user_id 有几百万个值
status: 200
1
2
3
4
5
6
7
# 好的写法:避免高基数的标签
- job_name: 'request'
metrics_path: /metrics
static_configs:
- targets: ['localhost:8080']
labels:
service: api

高基数的标签(如 user_id、request_id)会导致时序数量爆炸,严重影响 Prometheus 性能。

实际配置示例

生产环境推荐配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# prometheus.yml

global:
# 默认抓取间隔:15s
scrape_interval: 15s
evaluation_interval: 15s

# 存储配置:保留 30 天
retention: 30d

scrape_configs:
# 基础设施监控:间隔 60s
- job_name: 'node'
scrape_interval: 60s
static_configs:
- targets: ['node-exporter:9100']
relabel_configs:
- source_labels: [__address__]
target_label: instance

# 服务健康监控:间隔 15s
- job_name: 'service'
scrape_interval: 15s
static_configs:
- targets: ['service-monitor:8080']
metric_relabel_configs:
# 移除高基数标签
- source_labels: [user_id]
action: labeldrop

# 核心业务监控:间隔 5s
- job_name: 'core-business'
scrape_interval: 5s
static_configs:
- targets: ['core-api:8080']
alertmanager_config:
- alert_relabel_configs:
- target_label: severity
replacement: critical

告警规则优化示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# rules/service.yml

# 预计算 recording rules
groups:
- name: service_recording_rules
interval: 5s
rules:
# 1 分钟窗口的请求率
- record: service:request_rate:1m
expr: |
sum(rate(http_requests_total[1m])) by (job, service)

# 1 分钟窗口的错误率
- record: service:error_rate:1m
expr: |
sum(rate(http_requests_total{status=~"5.."}[1m])) by (job, service)
/
sum(rate(http_requests_total[1m])) by (job, service)

# 1 分钟窗口的延迟 P99
- record: service:latency_p99:1m
expr: |
histogram_quantile(0.99,
sum(rate(http_request_duration_seconds_bucket[1m])) by (job, service, le)
)

# 告警规则
- name: service_alerts
interval: 5s
rules:
# 错误率告警:阈值 1%,持续 1 分钟
- alert: ServiceHighErrorRate
expr: service:error_rate:1m > 0.01
for: 1m
labels:
severity: critical
annotations:
summary: "服务 {{ $labels.service }} 错误率过高"
description: "错误率 {{ $value | humanizePercentage }} 超过 1%,持续 1 分钟"

# 延迟告警:P99 超过 500ms,持续 2 分钟
- alert: ServiceHighLatency
expr: service:latency_p99:1m > 0.5
for: 2m
labels:
severity: warning
annotations:
summary: "服务 {{ $labels.service }} 延迟过高"
description: "P99 延迟 {{ $value }}s 超过 500ms,持续 2 分钟"

常见问题与解决方案

Q:抓取间隔设多少合适?

A:根据业务场景决定。普通业务 15s 够用,核心业务 5s-10s,基础设施 30s-60s。关键是分层策略,不同类型的指标用不同的间隔。

Q:告警延迟太高怎么办?

A:首先检查 scrape_interval 和 evaluation_interval 是否匹配。然后检查告警规则中的 rate 窗口是否太大,可以改用 recording rules 预计算。最后考虑将核心业务的抓取间隔设短。

Q:Prometheus 资源消耗过高怎么办?

A:优先检查标签基数是否过高(特别是 user_id、request_id 这类高基数标签)。然后考虑分层监控,将非关键指标的抓取间隔设长。最后考虑横向扩展,部署多个 Prometheus 实例分流。

Q:如何平衡监控质量与资源消耗?

A:采用分层监控策略,核心业务用短间隔,非核心业务用长间隔。使用 recording rules 预计算复杂指标,减少实时计算压力。定期审查指标和告警规则,删除无用的监控项。

Q:抓取间隔设到 1s 会不会影响被监控服务?

A:1s 的抓取频率确实会给被监控服务带来一定压力,但对于大多数 HTTP 服务来说,每秒一个请求基本可以忽略。关键是控制指标数量,避免暴露太多细粒度的指标。

Q:如何监控 Prometheus 自身的健康状态?

A:使用 Prometheus 监控 Prometheus(联邦集群),或者使用开源的 prometheus-operator。关注 scrape 成功率、查询延迟、存储使用率等指标。

监控最佳实践总结

  1. 分层监控:不同重要程度的指标使用不同的抓取间隔
  2. 合理采样:缓慢变化的指标用长间隔,快速变化的指标用短间隔
  3. 预计算优化:使用 recording rules 减少实时计算
  4. 标签基数控制:避免高基数标签导致的性能问题
  5. 定期审查:定期检查监控项的有效性,删除无用的指标
  6. 资源预留:Prometheus 的资源消耗跟指标数量正相关,提前规划好资源

写在最后

监控系统的配置没有标准答案,需要根据实际业务场景进行调整。

核心思路是:

  • 分层:不同重要程度的指标使用不同策略
  • 平衡:实时性、资源消耗、准确率之间找平衡
  • 优化:持续优化告警规则,减少不必要的延迟

如果你也在为监控配置困扰,希望这篇文章能给你一些参考。如果有问题或建议,欢迎交流。


作者:小六,一个在上海努力搬砖的运维工程师

Author:Margrop
Link:http://blog.margrop.com/post/2026-05-10-prometheus-scrape-interval-analysis-and-alert-optimization/
版权声明:本文采用 CC BY-NC-SA 3.0 CN 协议进行许可