凌晨三点,告警群里突然炸了
某中型互联网公司的运维老周,在2025年12月的一个深夜被电话惊醒。他们的核心交易服务挂了整整17分钟,监控大盘却一直显示"正常"。事后复盘时他才发现,问题的根源不是什么复杂的架构故障,而是一个再基础不过的Prometheus配置错误——scrape_interval被某位新同事误改成了10分钟。
这不是段子。这是Prometheus工程师在生产环境里最常见的"安静翻车"现场。你以为监控在跑,其实它已经失明了整整十分钟。从老周的故事里我们能挖出几个值得复盘的东西:Prometheus这东西,看起来谁都能上手,但真正能在生产环境里把它用明白的人,10个里不到2个。
这一篇不讲怎么安装、怎么配置YAML,这些文档官方写得比谁都清楚。我们讲的是踩坑——那些官方文档不会主动告诉你的、只有真刀真枪上过生产才会知道的5个实战陷阱。
陷阱一:采样间隔设错,监控直接"瞎"掉
Prometheus的scrape_interval默认值是15秒,听起来很合理。但老周团队栽过的那个跟头告诉我们:默认值在生产环境里几乎是不可信的。
为什么15秒会出问题
当你的服务集群规模从几十个节点膨胀到几百个,Prometheus单实例的抓取压力会陡增。一个常见的现象是:Prometheus自身开始出现missed scrapes,而用户毫无感知。因为Prometheus默认会在内存里"补"一个up=1的样本,让你以为目标还活着。
更隐蔽的是,如果你把scrape_interval调大到30秒甚至60秒配合一个较短的retention,数据的分辨率会肉眼可见地降低。老周团队那次事故中,事后回看metrics发现,CPU打满的尖峰只持续了不到40秒,却被10分钟的间隔"抹平"了,事后追因几乎无从下手。
正确的姿势
- 关键业务指标用5秒甚至1秒间隔,配合relabel压掉无用label
- 非核心业务可以放到federation或者remote_write到远端存储
- 一定要监控Prometheus自身的scrape_duration_seconds和scrape_samples_scraped
陷阱二:标签滥用,TSDB被你玩崩
Prometheus的标签设计是它的灵魂,也是它的"原罪"。在Prometheus工程师的圈子里有一句玩笑话:"label用得有多爽,OOM那天就有多惨"。
高基数标签的杀伤力
假如你给一个指标加上了user_id标签,看似查询很方便,实际上每个不同的user_id都会在内存里生成独立的时间序列。一个日活百万级的业务,光这一项就能产生上千万条active series。Prometheus的内存占用会从几个G直接飙到几十G,查询慢得像老牛拉车。
据行业内部观察,2025年下半年某电商平台在促销期间因为一个工程师临时给trace_id加了个标签,整个监控体系直接挂了40分钟,损失了数百万的GMV监控数据。
实操建议
- 高基数字段(用户ID、订单ID、TraceID等)绝对不要直接打label
- 用metric_relabel_configs在抓取后立即drop掉不需要的label
- 定期跑tsdb_analyze命令,定位那些series数量异常飙升的指标
陷阱三:告警规则写得像散文,关键时刻全静默
Prometheus的告警体系(Alertmanager)是整个监控的"喉咙",但90%的团队都把它写成了"噪音机器"。
常见的两个极端
第一种是告警疲劳:阈值设得太敏感,半夜三点手机响个不停,工程师开始集体mute,最后真出问题没人看。第二种是过度聚合:把所有指标揉成一团用一个大阈值糊弄过去,结果某机房断电这种重大事故只发了一条"CPU使用率偏高"的告警,根本没人当回事。
真正成熟的Prometheus工程师会怎么做?答案是分层告警。把告警分成P0(业务不可用)、P1(性能降级)、P2(资源预警)三层,每层配不同的通知渠道和响应SLA。
几个反常识的细节
- for: 子句不要随便省。省了就会一直闪报,加上5分钟反而能过滤掉很多抖动
- rate() 函数选错窗口会导致数据失真,比如5分钟窗口在突发流量下几乎没用
- 告警文案要写"影响",不要写"指标"。不要写"CPU>90%",要写"订单服务响应延迟超过阈值,可能影响下单转化率"
陷阱四:存储规划一塌糊涂,三个月后数据全没
Prometheus的本地存储是设计上的妥协,不是长期方案。它的WAL+block存储模式决定了:单实例的retention上限基本就是几周到几个月,磁盘一满,新数据直接被丢弃。
两种主流的解决方案
方案A:Thanos,把Prometheus的block上传到对象存储(S3/OSS/COS),查询时通过Sidecar或者Querier聚合。适合云原生场景,运维成本相对高。
方案B:VictoriaMetrics,作为Prometheus的drop-in replacement,单实例可以扛住几亿个active series,存储压缩比也相当优秀。适合规模较大、对成本敏感的业务。
据公开数据显示,2026年Q1某头部云厂商的内部监控数据采样量同比2025年增长了300%以上,这意味着"数据全丢"的事故风险正在被指数级放大。
几个容易被忽略的细节
- remote_write不是万能的,网络抖动会导致数据丢失,记得配queue_config
- 压缩存储虽然省钱,但查询性能会下降,冷热数据分层是必须的
- 不要在Prometheus里跑长周期(比如1年以上)的趋势查询,瓶颈会非常明显
陷阱五:高可用做了一半,反而更脆弱
很多团队会拍胸脯说"我们Prometheus做了高可用",但仔细一问,其实只是启了两个实例,各抓各的数据。真正的HA要做对,至少包括以下三层:
三层HA的完整形态
第一层是采集层冗余:两个Prometheus实例同时抓取同一批target,保证任一实例挂了数据不丢。这是最基础的。
第二层是Alertmanager集群:用Gossip协议做去重和分发,避免重复告警。这一步很多团队直接跳过,结果就是同一个故障发了20条告警,运维群直接被刷屏。
第三层是存储层解耦:通过remote_write把数据同时写到多个存储后端,本地TSDB只是"短期缓存"。这才是真正能扛住节点宕机的架构。
一个真实的反面案例
某金融科技公司在2025年Q3的一次机房断电事故中,由于Prometheus只部署了单实例,所有告警和历史数据全部丢失,事后追责时发现:备份脚本压根没跑过,因为"大家都以为Prometheus自己会做"。这种"想当然"的运维心态,是高可用最大的敌人。
回到开头那个问题
老周那次事故之后,他们团队做了一次彻底的监控体系重构。新加了一条核心原则:"监控自己也要被监控"。所有Prometheus实例的scrape成功率、内存使用、磁盘占用、WAL写入延迟,都被纳入了二级监控。
这听起来像是一句正确的废话,但能做到的团队真的不多。在我们接触过的几十家中大型公司里,能把Prometheus工程师这个岗位真正"职业化"的,不到三分之一。多数情况下,监控只是某个运维工程师的副业,出了问题大家互相甩锅。
所以最后一个延伸思考留给你:如果你们公司的核心业务明天凌晨三点挂掉,你的Prometheus能不能在第一分钟内告诉你到底是哪里挂了?如果你犹豫了哪怕一秒钟,那么这篇文章里讲的5个陷阱,大概率正在你们生产环境里悄悄发作。监控这件事,永远是"不出事没人理,出了事救不了",而我们能做的,就是尽量让自己不要成为那个被电话叫醒的老周。
Zyra