报错是这么冒出来的。2 核 4G 的 Prometheus 2.45 拉 800 个 target,15 秒一轮,targets 页面成片 context deadline exceeded,机器 CPU 常驻 90%,数据盘 await 到 30ms。
把日志和配置对完,能解释这个现象的基本就这几处。scrape_timeout 用默认 10 秒,单轮抓取任务排队,排在后面的超时。也可能是部分目标 /metrics 生成要 3 秒以上,JMX exporter 尤其明显。
不容易想到的是,WAL 写入慢,append 阻塞采集循环,抓取队列表越堆越长。
第一件事是列出失败的 target 与原因
curl -s localhost:9090/api/v1/targets | jq -r '.data.activeTargets[] | select(.health!="up") | [.scrapeUrl,.lastError] | @tsv' | head
随后把慢目标的超时单独放大
在 job 里写 scrape_timeout: 30s 与 scrape_interval: 60s
丢大指标减轻序列数
metric_relabel_configs: - source_labels: [__name__] regex: 'go_.*' action: drop
剩下的就是看自身存储是否拖后腿
promtool tsdb analyze /var/lib/prometheus/data | head -20
同一份数据我导出了两份,一份留底,一份拿来试。
这类问题以前遇到过,但这次的触发条件和上次不一样。
恢复的判定其实很直接。targets 页面 down 数为零,scrape_duration_seconds 的 p99 低于超时值的一半,Prometheus 自身 CPU 回落到 50% 以下且 WAL 目录增长平稳。
抓取超时先分是自己慢还是目标慢,把慢的 job 单独隔出来最省事;一味加并发只会让排队更长。如果同一现象隔几天又出现,说明根因没找到,别当偶发处理。
