PLFM_RADAR是我最近小半年一直在维护的一个内部项目,名字起得很直白——Platform Radar,平台雷达。当初起这个名,就是想做一套能“盯着平台看”的系统,不是只看服务器CPU有多高,而是真能看出业务有没有在正常跑、用户体验有没有悄悄变差、系统是不是在某个角落偷偷漏水。这篇文章就把这个项目的完整思路、落地过程、踩过的坑,一次性整理出来。如果你也在做平台监控、稳定性建设,或者正准备从零搭一套预警系统,这篇应该能帮你省掉不少弯路。
1. 项目缘起:为什么需要一套“平台雷达”
1.1 平台出问题的代价,往往是一连串的
先说一个真实场景。我们平台跑着几个核心模块,平时看起来一切正常,直到某天有用户反馈"页面打不开了"。我登录服务器一看,负载确实高了,内存也不够,但问题是——这些指标早在半小时前就该报警了,为什么没人发现?
因为那会儿我们只有最基础的监控:看CPU、看内存、看磁盘。说实话,这些指标就像人的体温和血压,真出问题的时候已经很严重了。而平台的"隐性疾病"——接口变慢、错误率悄悄上升、某条链路在特定时段超时——不是体温计能测出来的。
这是我做PLFM_RADAR的第一个动机:我想要的不是体温计,而是雷达。雷达的特点是主动扫描、提前发现、持续跟踪。平台上的每一个关键节点、每一条核心链路,都该有对应的探测信号,一旦偏离正常范围,就得跳出来告诉值班的人"这里有情况,来看一下"。
1.2 PLFM_RADAR的定位与整体思路
PLFM_RADAR要解决的,是三层问题。第一层是看得见:平台现在是什么状态,哪些模块在正常服务,哪些已经处于亚健康。第二层是看得懂:状态异常时,是哪里先出了问题,影响面大概多大,该找哪个团队处理。第三层是来得及:从发现异常到通知到人,延迟要控制在分钟级,不能让异常"裸奔"太久。
整体思路其实不复杂:采集数据、集中存储、规则判断、触达通知。听着和传统监控没区别,但真正落地的时候,难点在细节。哪些数据值得采、阈值怎么设、通知发给谁、告警怎么避免重复轰炸,每一个问题都能磨掉你大把时间。PLFM_RADAR在做的事情,就是把这一整套流程串起来,让它从"能监控"变成"能预警、能定位、能闭环"。
1.3 它适合谁来参考
如果你属于以下三类人,这篇文章应该对你有用:第一类是开发负责人或运维负责人,手里管着多个服务,正觉得现有监控"什么都看着,什么都不精";第二类是后端开发,想给自己负责的模块加一层业务层面的健康检查,而不只是看基础资源;第三类是刚接触监控体系建设的人,想找一套可以参考的落地路径,少踩几个坑。
项目本身不大,技术选型也都是开源的,没有用特别冷门的东西。你完全可以照着这个思路,在自己的环境里搭一套出来。
2. 整体架构:雷达的四个核心部件
2.1 数据采集层:先有数据,才有判断
雷达不能凭空发现目标,它需要电磁波反射回来的信号。PLFM_RADAR的第一件事,就是搞定数据信号源。
我们接的数据源分四类。第一类是基础设施指标,包括CPU、内存、磁盘、网络IO,这类数据成熟稳定,标准agent都能采。第二类是应用层指标,比如接口QPS、P99延迟、错误码数量、JVM堆内存,这类数据需要应用主动暴露,通常通过埋点方式实现。第三类是业务指标,比如订单创建数量、支付成功率、某个核心流程的完成时长,这类数据最能反映用户体验,但也最容易被忽略。第四类是日志与事件,系统出现Exception、超时、熔断,这些都是重要信号,不能只躺在日志文件里睡大觉。
有一点我要特别强调:很多人做监控,第一步就扎进采集工具里,纠结用哪个agent、配哪些插件。但以我的经验,第一步应该先列指标清单。把平台上重要的模块、重要的接口、核心的业务动作写出来,挨个问一句:如果这个环节出问题了,谁能第一时间看出来?答案就是你需要采集的指标。
2.2 指标存储与计算层:时序数据是主燃料
数据采上来之后,要有一个地方能存、能查、能做计算。我们用的是时序数据库,专门处理这种按时间排列的指标数据。就目前的体验来说,时序库的压缩率、查询性能、聚合能力,都远好过拿MySQL硬扛。
存储层的设计上,三个细节很关键。
第一是标签体系。采集数据的时候,一定要想好怎么打标签。比如接口维度,服务名、环境、接口路径、实例ID,这些都要作为标签存进去。将来你想看"某个服务的所有实例"还是"某个接口的P99",全靠标签筛出来。打标签的时候宁可多一些,也别抠门,后面加标签比改标签麻烦得多。
第二是采样粒度。不用所有数据都存原始值。秒级数据保留一周,分钟级数据保留一个月,小时级数据保留一年,这种分级保留策略能省大量空间。我们早期不舍得丢弃秒级数据,结果存储成本蹭蹭涨,查询速度也跟着变慢。
第三是预聚合。常用的聚合查询,比如按服务、按接口算平均值和百分位值,提前算好存在单独的表中,查询响应会快非常多。雷达要实时扫描,查询太慢就等于雷达转不动。
2.3 告警引擎:雷达的核心是预警
如果所有监控数据只是安静地躺在库里,那和没有监控没什么区别。PLFM_RADAR真正有价值的部分,是告警引擎。
告警引擎做的事情,可以拆成三步。第一步是配置规则,每个规则定义什么条件下触发告警,比如"支付接口P99连续3分钟大于800毫秒"或者"订单失败率5分钟内超过2%"。第二步是执行评估,引擎定期扫描新写入的数据,匹配规则条件。第三步是状态管理,一条告警触发之后,是持续告警、还是恢复后自动解除,都要有明确的状态机管理。
这里有个容易忽略的点:告警规则要支持分级。我们把告警分成P1、P2、P3三级,P1是核心业务不可用,P2是功能异常或性能劣化,P3是潜在风险。不同级别对应不同的通知方式和响应时限。如果不分级,小事也紧急通知,大事反而被淹没在告警群里,这雷达就会失灵。
2.4 展示层:给决策者的“雷达屏幕”
有了数据和告警,还需要一个直观的界面。PLFM_RADAR的展示层,分了三个视图。
第一个视图是总览大屏,面向管理层和值班人员。一眼能看到平台整体是否健康,重点模块有没有飘红。这个视图不需要太多细节,越精简越好。第二个视图是模块洞察,面向具体模块的负责人,可以看到自己负责的服务各项指标的趋势图、告警历史、当前状态。第三个视图是链路追踪,面向排查问题的人,从一条业务链路的角度,把涉及的各个环节串起来看,方便定位瓶颈。
我遇到过一些团队,觉得界面好看很重要,花了很多时间调颜色、调布局。我的看法是,界面先能用、清晰,再谈好看。报警信息能不能一眼看懂,状态异常能不能快速定位到模块,这个优先级比美观高得多。
3. 实操落地:从零搭一套PLFM_RADAR
3.1 第一步:明确要监控什么,而不是先装工具
我见过最普遍的错误,就是先搭一套Prometheus,装上一堆exporter,然后发现数据倒是有了,但不知道该看哪些。
PLFM_RADAR的落地,第一步一定是在纸上完成的。把平台的核心模块列出来,比如:用户服务、订单服务、支付服务、消息推送服务。每个模块回答三个问题:
- 这个模块最重要的功能是哪个接口?
- 这个接口正常响应的标准是多少?比如P99小于500ms。
- 如果这个接口开始报错,最早能感知到的指标是什么?
这套问题问下来,你的监控清单基本就有雏形了。我们最终形成的清单大概二十多项,每一项都对应着一个明确的"为什么监控它"的答案。后面所有采集配置、告警规则,都是从这个清单里来的。
3.2 第二步:采集端的部署与配置
采集方案我们用两路并行。一路是标准agent采集系统资源,部署在每台机器上,上报CPU、内存、磁盘、网络。另一路是应用侧埋点,通过在各个服务里接入SDK,主动上报接口指标和业务指标。
部署上有个顺序要注意。先把时序库和采集端搭起来,再逐步给应用加埋点,不要一上来全量改动。我们当时先挑了两个核心服务试点,确认数据上报链路稳定、面标签设计合理,才铺开接入。试点阶段花了大概三天,后面全量接入反而没出什么大问题。
这里我给大家一个关键配置建议:埋点的采样率不必是100%。对于高QPS的接口,全量采集会带来额外的性能开销。我们采用的是:核心接口全量采集,非核心接口按10%采样,低流量接口全量。这样一个折中方案,既保证了关键数据完整,又控制了对业务的影响。
3.3 第三步:告警规则的编写逻辑
告警规则的编写,是PLFM_RADAR项目里我们迭代次数最多的部分。起初规则写得粗糙,要么阈值太保守导致天天误报,要么太宽松真的出事没动静。后来总结出一套心得,写规则要满足三个原则。
第一,用趋势代替静态值。比如"P99超过800ms持续5分钟",比"P99超过800ms"立刻触发更合理。平台流量有高峰有低谷,静态阈值很容易在高峰期误报、在低峰期漏报。加一个持续时长的条件,相当于让雷达多看几次再下结论,虚警率大大降低。
第二,异常必须落在具体对象上。告警信息里必须说清楚是哪条链路、哪个服务、哪个接口出问题。不要发一条"响应时间过高"这种让人摸不着头脑的告警,收到告警的人没法行动,这条告警就是废的。
第三,设置恢复和升级机制。一个告警触发后,如果在约定时间内没处理,要能自动升级通知到上一级负责人。同时,恢复之后要自动发一条恢复通知,让所有人知道警报解除。没有恢复机制的告警,就像火警响了但没人告诉你火已经灭了,值班的人心里永远悬着。
下面是我们某条核心链路告警规则的一个简化示例:
rules: - name: payment_p99_high condition: metric: payment_service_p99_latency_ms op: ">" threshold: 800 duration: 5m severity: P2 target: payment_service_oncall message: | 支付服务P99延迟已超过800ms并持续5分钟。 当前值:{{ value }} ms 接口:{{ interface }} 最近30分钟趋势:{{ trend_url }}写规则的时候,message这个字段一定要用心。值班的人收到告警,应该立刻知道三件事:什么问题、影响多大、下一步去哪看。把定位信息直接塞进告警消息里,能省掉无数来回询问的时间。
3.4 第四步:通知链路与值班兜底
告警触发之后,通知链路决定了人到底能不能及时看到。我们用的是"先IM,后短信,最后电话"的三级触达方式。
P3级别的告警,只在即时通讯群里发一条消息,由值班人员有空的时候看。P2级别的告警,先发即时通讯消息,如果10分钟没确认,短信再发一次。P1级别的告警,即时通讯消息、短信、电话同时触发,确保核心人员能第一时间响应。
这里要特别提醒:通知一定要设计"确认"机制。收到告警的人需要有一个操作,把告警标记为"已认领"。否则一条告警群里每个人都看到,最后可能谁都不处理,大家都有一种"别人会管"的错觉。我们的做法是,告警消息上带一个确认链接,点击即认领。超过预设时间未认领,告警升级。
通知链路本身也要监控。我们维护了一个监听进程,定时向一个探测地址发送心跳。如果真的发生大规模故障,网络都不通,通知链路本身也可能挂掉。这时候要保证电话通知不依赖内网环境,能走独立通道触达。
3.5 第五步:一套够用的可视化仪表盘
PLFM_RADAR的仪表盘,我的设计原则是"有点击路径,而不是一屏塞满"。总览页只放最重要的六到八个卡片:核心服务可用率、支付成功率、P99延迟、系统负载、告警数量、今日重大事件。每张卡片上如果出现异常,点击进去就是对应的详情页。
详情页的布局也有讲究。最上面是"当前状态摘要",自动生成一段文字,比如"支付服务当前P99为1.2秒,高于阈值,最近15分钟错误率从0.1%升至0.8%"。这一步非常有用,它把年轻同事上手排查的门槛降低了一大截,不用看懂一堆曲线,先读懂这句话再说。
中间部分是关键指标的趋势图。趋势图的选择上,我建议优先看P50、P99和Max三条曲线,逐层递进。P50代表多数人的体验,P99代表最差情况的体验,Max代表极端情况。如果P50正常、P99飙高,说明少数非典型请求出了问题;如果P50和P99都高,那就是整体都慢,问题往往在公共资源上。
4. 实战中的坑与排查记录
4.1 告警风暴:一次阈值设置不当引发的“群消息灾难”
项目上线第二周,我们经历了一场典型的告警风暴。凌晨两点,群里开始刷屏。当时新加了一条规则,针对某个数据库连接池的使用率,阈值设在70%,持续1分钟就触发。结果业务高峰一到,连接池使用率在70%到75%之间来回抖动,告警触发、恢复,再触发、再恢复,循环了一个多小时,群里刷了几百条消息。
那次之后,我把写告警规则的标准提高了:阈值必须基于一周的长期数据显示来定,先看趋势再设值,而不是拍脑袋设一个"看起来合理"的数字。**具体操作是:先开通"试运行"模式,规则只记录不通知,持续运行三天,统计触发频次,再决定是否正式开启通知。**按这个流程走下来,新规则的准确率明显高了,群里也安静多了。
4.2 数据断点:时间线对齐问题
有一段时间,告警总在下午三点半左右触发,但过了十分钟查看数据又恢复,而且找不到任何明显的原因。后来仔细排查发现,是时序数据写入出现了延迟,部分数据点比实际时间晚了十几分钟才入库。我设置的窗口查询正好卡在数据缺失的区间,导致误判。
这个问题的教训有两个。一是告警查询窗口必须考虑数据延迟,尤其是基于分钟级数据的规则,要在时间上留出偏移量。二是要有一套数据完整性的校验机制,定时检查最近几分钟有没有数据断点,如果发现某类指标缺失超过特定比例,执行自身发出告警,而不是拿着残缺数据做判断。雷达如果屏幕上都是雪花点,首先应该怀疑雷达本身出了问题。
4.3 误报与漏报的平衡
误报和漏报就像天平的两端,压了这边,那边就翘起来。刚开始调规则的时候,我极度追求"零误报",结果规则越来越严,最后变成了"基本不报"。直到有一次,用户论坛里开始有人抱怨页面加载很慢,我们的告警却毫无反应,我才意识到严重偏向一方没有任何意义。
现在的平衡思路是:对P1级核心链路,宁愿多报,不能漏报。P1级告警的本质是"平台可能已经出大事了",这时候多叫几个人起来看一眼,成本远低于一次用户不可用的事故成本。对P2、P3级则相反,要尽量精准,减少无意义的打扰。这就像家里装的是火警报警器,而不是烟雾报警器——火警误报多让人烦躁,但烟雾漏报可能烧了整栋楼。
4.4 从被动响应到主动预见
PLFM_RADAR跑通之后,收获最大的不是"告警变快了",而是我们开始能做"提前处置"了。
举一个例子:支付服务的成功率在工作日晚上八点到十点之间会有一个小低谷,以前我们以为是用户流量波动。后来把历史数据拉出来看,发现每个周三的晚上八点半左右,都会出现一分钟成功率下降,然后自动恢复。顺着时间线索查下去,定位到一个定时任务的资源抢占问题。这个结论不是靠紧急排查查出来的,是靠雷达持续扫描积累数据之后分析出来的。作为参考,我们在后续迭代中,把预警重心逐渐从"故障发现"转移到"异常趋势预判"上,开始给平台做"体检报告",而不是等着生病再急诊。
5. 关于项目迭代与后续扩展
PLFM_RADAR做到现在,基本轮廓已经比较完整了。但说实话,监控系统这东西是永远做不完的,业务在变,平台的复杂度也在变,雷达要盯的目标也得跟着调整。目前我们正在做的几个扩展方向,在这里一并写出来供大家参考,也许你的平台上也会碰到类似需求。
第一个方向是智能基线。现在很多告警规则还是依赖人工设定固定阈值,但有些指标的波动是有周期性的,比如工作日晚高峰流量是早上的好几倍。固定阈值要么在高峰误报、要么在低谷漏报。我们正在尝试用过去四周的同时间段数据做动态基线,让告警规则跟着历史趋势走,而不是拍脑袋定一个常数。
第二个方向是根因定位辅助。现在告警虽然能告诉我们"哪个指标出问题了",但还是需要人去看拓扑关系,推断是不是底层数据库抖动连累了上层接口。我们准备把服务的依赖关系加进雷达的模型里,告警触发时自动展示上下游可能的关联路径,相当于给值班人员一张"事故地图",能少翻不少日志。
第三个方向是用户视角的监控。传统的雷达盯着服务器、接口,但用户真正在意的是"我能不能顺利下单""支付会不会转圈"。我们计划在前端关键路径上增加埋点,把页面的真实加载时间、操作成功率也纳入监控范围。这样雷达盯着的就不只是后端这个"厨房"有没有在正常出菜,还包括"客人吃饭"的整体体验。
最后再分享一个小感受:做PLFM_RADAR这个过程,最大的收获不是代码和告警规则,而是让我重新理解了“监控”这件事。监控不是装个工具就能完事,它是把对业务的思考变成阈值、把对系统的理解变成规则的过程。每一个被写进配置文件的条件,背后都是对平台环节的重新认知。如果你也在搞类似的项目,不用追求一次到位,先把最核心的几条链路盯住,跑起来,再逐步扩大雷达的扫描范围。