
1. 项目缘起为什么需要一个叫“PLFM_RADAR”的东西年初我们团队接到一个挺头疼的活儿内部十来个业务系统跑在同一套基础设施上隔三差五就有人跑过来说“页面好慢”“任务又失败了”“资源又不够了”。每次排查都要翻好几套监控工具时序库里捞半天数据才能拼出一个大致脉络。痛了几次之后我们决定自己动手做一套平台级的“雷达”——这就是PLFM_RADAR的起点。PLFM_RADAR这个名字PLFM取自PlatformRADAR很直白就是雷达。它干的事情可以概括成一句话把散落在各系统里的运行状态数据统一收上来用一套规则去扫描、识别、预警让平台上的异常“看得见、说得清、追得到”。和传统单点监控不一样它更关注平台整体视角某个服务的抖动会不会拖垮依赖链某台机器的水位上涨是不是全局限流的前兆这些跨系统的关联判断才是这套东西真正解决的核心问题。如果你也面临相似的场景——系统不多但依赖复杂监控工具各管一段出了问题靠人肉翻日志那这篇总结应该能给你一些可以直接抄走的思路。2. 整体设计思路先画场景再定架构2.1 先想清楚要“看见”什么做监控系统最容易犯的错是一上来先选工具选完才知道自己到底要监控什么。我们反过来先花了两周时间把平台上的“场景”梳理了一遍最后归成三大类资源水位类CPU、内存、磁盘、带宽这些是基础设施的“血压计”异常往往有明确的数值阈值可判定。服务状态类接口响应时间、错误率、任务队列积压量、进程存活状态这是业务系统的“心电图”比纯资源监控更贴近用户体验。依赖链路类A服务调用B服务、B依赖数据库和缓存某一段变慢会顺着调用链传导。这部分最容易被单点监控漏掉却是平台事故的“重灾区”。这三个场景对应三种不同的数据特征资源数据是数值型的周期性强服务状态数据有瞬时抖动需要平滑处理链路数据强调关联性需要做拓扑归并。设计雷达的第一步就是让下面的每一层都朝着这三个目标去服务。2.2 四层结构采集、传输、存储、分析PLFM_RADAR的架构不复杂没有搞微服务那一套花活。整体分成四层采集层每台机器部署一个轻量采集器负责收集系统指标、服务探针数据以及从各业务系统已有的日志里抽取关键状态。传输层采集器把数据推送到统一的接入网关网关做基础校验、清洗和限流。这里只用简单的HTTPJSON协议不引入消息队列中间件把故障面控制到最小。存储层指标数据进时序数据库链路和事件数据进文档型存储原始日志继续留在原来的日志平台。不强制“大一统”各归各位。分析层定时任务负责计算聚合指标、执行告警规则前端是一个简单的控制台展示总览面板和告警列表。这个设计有一个很重要的取舍采集和存储分离、存储和分析分离。哪怕分析层挂了数据还在库里事后还能回溯补算哪怕控制台访问不了告警通知也会单独走消息通道发出来不影响人接收。2.3 为什么不用现成的开源全家桶一把梭肯定有人问Prometheus Grafana Alertmanager 不是挺好的吗为什么还要自己写一套说实话我们内部确实一直在用这些工具单点监控和可视化它们做得非常好。但我们的痛点是跨系统关联分析这块用现成方案拼起来非常别扭Prometheus擅长拉取数值指标可我们要判断“支付服务和订单服务的调用关系是否健康”这需要事件数据链路数据指标数据放在同一个分析上下文里计算。硬靠PromQL硬写也能做但规则一多、逻辑一复杂维护成本会直线上升最后变成只有几个人能看懂的“天书”。所以我们的策略是基础监控继续用现成组件PLFM_RADAR专注于做平台层的关联分析和统一告警。它不替代Prometheus而是在上面加了一层“雷达视角”——把下游监控数据汇进来再用自己的规则引擎做二次加工。这个定位从一开始就很明确后面所有开发都围绕这个边界推进。3. 核心细节解析数据模型与指标计算3.1 用“实体指标标签”组织所有数据雷达系统里最基础的概念是监控实体。一台机器、一个服务实例、一个数据库连接池都是实体。每个实体带一组静态属性比如所属机房、部署单元、负责人同时带一系列动态指标比如CPU使用率、请求量、错误数。实体之上是标签体系这部分是关键中的关键。我们用了五类标签环境标签生产、预发、测试归属标签业务线、子系统、团队位置标签机房、机架、容器节点角色标签入口服务、中台服务、存储节点版本标签发布批次、代码版本标签不是随便打的它直接决定了雷达能画出什么样的“关联图”。比如某个预发环境的服务变慢如果所有数据都有环境标签就可以一键过滤出同一发布批次的所有实体快速判断是不是这次发布引入的回归。3.2 指标计算的三个关键公式与场景实时计算层最常用到的有几个指标看起来简单但细节里全是坑。第一个是滑动窗口请求成功率业界通用的做法是取最近5分钟的样本成功率 (5分钟内成功请求数 / 5分钟内总请求数) * 100%这个公式单独看不难难在“5分钟”怎么定义。如果按自然时钟的整点切窗口流量毛刺会剧烈抖动我们改成了滚动窗口每10秒计算一次最近5分钟的数据相当于一个不断往前平移的窗口这样曲线平滑很多也更容易和真实用户体验对齐。第二个是容量水位预估这个我们用在磁盘和内存上比较多预计耗尽时间 当前剩余量 / 最近30分钟的平均消耗速率这个指标非常直观比如磁盘还剩80GB最近半小时平均每小时消耗2GB那预计40小时会写满。它比单纯的“使用率超过80%”告警更有实际意义能给运维留出精准的处置时间窗口。第三个是依赖影响度的权值这个稍微复杂点依赖影响度 被依赖方故障时间窗口内 / 调用方总请求数量 * 100%假如支付服务在10分钟内错误率飙升那我们要看这10分钟里有哪些上游在调它、各自调了多少笔。影响度越高说明事故的“辐射面”越大告警级别也要相应上调。这个指标让雷达不只是报“谁坏了”还能说“大概影响了谁”。3.3 存储选型与数据生命周期时序数据我们最终选了ClickHouse原因是写入吞吐高、压缩比好、聚合查询快。数据按天分区原始指标保留7天5分钟聚合保留30天1小时聚合保留半年。这样既保证近期排障时的精度又控制了存储成本。实测下来单机写入速度能稳定在每秒十几万点查询95%在200毫秒内返回这个性能对内部平台完全够用。日常容量大约每天产生20GB原始数据压缩后大概6GB一年下来的存储成本完全可以接受。事件数据则进了Elasticsearch主要存告警触发记录、规则变更记录、人员确认操作。到这里出现了一个很常见的坑时序库和文档库的数据对不上。比如告警记录显示10:05触发可时序库里10:04到10:06的指标恰好因为采集器重启而缺了一段。后来我们统一了时间规范所有时间戳一律用毫秒级UTC存库展示层再转成服务器本地时间并在告警记录里同时保存“触发批次ID”这样两边数据就能严格对齐了。4. 实操过程与核心环节实现4.1 采集器的实现要点采集器我们用Go写部署方式很简单编译成静态二进制丢到机器上配一个systemd服务。每个采集器有唯一ID启动时先从配置中心拉取自己的采集任务列表然后按固定的间隔循环执行任务。每个采集任务是一个插件输出统一的指标结构{ entity_id: srv-order-prod-01, metric: request_total, value: 43520, timestamp_ms: 1704233600123, tags: { env: prod, biz: order, zone: sh-01 } }上报走批量接口每10秒攒一批最多攒500条或10KB就推一次。这里有个“攒批”策略值得提一下宁可本地稍微多攒几秒也要减少HTTP连接次数。前期我们每2秒就推一次网关和采集器之间的TCP连接数和垃圾回收压力明显偏大后来改成10秒批量推送整体CPU占用反而降了。采集器自身有一个看门狗进程每隔30秒检查主进程是否还响应不响应就自动重启重启时用状态文件续接避免重复上报旧数据。另外采集器不能把自身消耗的资源也当成系统异常报上来——我们为此专门把采集器的CPU、内存使用量放进了独立进程组并在上报之前过滤掉。4.2 告警规则引擎阈值不是拍脑袋定的告警规则引擎是整个雷达的核心研发过程中我们反复打磨。规则大致分为三类规则类型触发条件示例默认周期告警级别资源阈值CPU使用率连续5分钟90%每60秒评估一次P2聚合统计某服务5分钟错误率5%每30秒评估一次P1联合判断磁盘剩余预计24小时每10分钟评估一次P1规则不是一次性写死而是配置在规则表里后续可以在控制台上调整阈值而不需要重启服务。比较关键的设计是连续N个周期都触发才真正告警。比如错误率规则设置“连续3个周期每周期30秒错误率大于5%才触发”这能过滤掉绝大多数瞬时抖动造成的误报。代价是延迟变长最多90秒才出告警但实际操作中发现这个延迟换来的是告警置信度的大幅提升非常划算。告警产生后进入“静默期”机制同一实体同一规则触发的告警默认10分钟内不重复通知除非级别升级。比如从P2升级到P1会立即重新通知。如果同一个实体连续1小时不断触发同类告警系统会发送“持续告警汇总”把这段时间的触发次数、峰值、相关实体都汇总成一条而不是刷屏。4.3 控制台面板给不同角色看不同的信息控制台分成三个视角值班视角只看当前正在处理的告警列表、待确认工单、以及平台整体健康分。健康分是我们自创的一个0到100的指数由资源水位、服务可用性、依赖健康度加权计算得出方便快速了解现在“大不大事”。开发视角按业务线隔离研发只能看到自己负责的实体和对应的指标曲线支持按标签下钻。这里用到了前面说的标签体系数据权限也通过标签来控制效率很高。管理者视角聚合展示SLA趋势、告警趋势、故障时长分布等周报型数据不需要实时数据从聚合表中跑预计算任务生成。前端没有用太重度的方案就是React 一个开源时序图组件加上WebSocket推送实时告警。整体代码量不大但给使用者的体感非常专业——因为信息密度高、层级清楚。5. 常见问题与排查技巧实录到这里分享几个我们实际运营中遇到的经典问题每一个背后都对应一个“别踩的坑”。5.1 时序数据库的“写放大”问题问题现象ClickHouse磁盘占用增长速度远超预期一周发现比预估大了好几倍。排查过程先是看分区大小发现单日分区数据量异常。进一步查看发现有一个采集任务误配了“每次上报都附带当前CPU的瞬时快照”这个指标基数特别大——因为每台机器上有几百个进程每个进程每秒一个点一天数据量轻松上亿。解决办法把高基数指标全部降频进程级别的指标从10秒采集改为5分钟采集同时给写入链路加了采样规则对于老机器上的非关键指标自动抽稀。这套组合拳之后日增数据量降了70%。这个问题的根因其实就是标签基数爆炸。给读者的一个建议设计指标时一定要明确“指标是用来回答什么问题的”如果答不上来那就别采集数据也是成本。5.2 告警风暴一次发布引发的几百条通知问题现象某次上线新版本后相关服务因为日志里一个错误的等级配置导致错误率计算全部超标一瞬间触发几百条告警值班手机直接被刷爆。排查过程回看告警记录发现触发点全部集中在同一批次发布的十几个实体上。这个问题光看单条告警很难发现规律但我们当时做了一个“告警聚类”的后处理任务按标签发布批次、部署单元、依赖服务对告警做分组如果同一分组内实体数量超过一定比例就自动合并成一条“群体性告警”并在标题里标注批次信息。改进后的效果非常明显类似的发布问题再出现时告警从几百条收敛为一两条而且信息量反而更大——直接告诉你是“这批发布引起的”。这里想说一个心得告警系统的价值不是通知越多越好而是通知越准、越少越好。调试告警规则时宁可漏掉一两个无关紧要的边缘告警也不要让平台产生“狼来了”效应——当值班人员发现每条告警都是真的问题、而且告警信息直接指向根因时整个团队的响应速度会快一个量级。5.3 时间不同步导致的分析错乱问题现象某次排查发现A服务调用B服务的数据在雷达里显示B服务响应时间正常但A服务显示超时两边时间线完全错位。排查过程查了一遍发现有几台服务器的时间同步服务没配置好系统时间和标准时间差了将近40秒。而链路数据是按时间戳做关联的几十秒的偏差足以让整个调用链视图“断裂”。解决办法在所有机器上强制部署时间同步客户端并在采集器里增加一个“时间偏移检测”能力——采集器会在心跳包里带上本机时间网关收到后对比自己的时间一旦偏移超过5秒就在该实体的标签里打上“clock_offset”标记让它不再参与链路分析并定时触发告警提醒运维修复。同时链路数据关联不再只依赖时间戳而是引入了“请求ID透传”这也是彻底解耦的有效手段。这个教训挺典型的分布式系统里时间不同步是一切疑难杂症的温床不只是监控系统很多业务问题排查到最后都会绕回时间上来。5.4 常见问题速查表问题可能原因优先排查动作指标曲线出现断崖式下跌采集器重启、网络分区、网关限流查看采集器心跳日志检查网关连接数告警触发了但图表无数据告警规则针对聚合表而原始数据已过期清理检查聚合任务是否执行成功比对数据时间范围历史数据对不上服务器时区设置不一致统一用UTC8检查服务器时间同步状态面板加载极慢查询了未加时间范围的大范围原始表强制限制原始表查询时间范围推荐使用聚合表相同告警反复触发静默期设置过短或规则评估粒度过细把静默期延长至15分钟调整评估周期对齐业务波动6. 避坑指南与经验复盘6.1 规则配置的“灰度”意识告警规则上线之前最好先设置成“观察模式”。观察模式的意思是规则照常计算、照常生成告警事件但不推送给任何人只是落库。我们花了两周时间把所有新规则都先用观察模式跑一遍收集触发频率、误报比例调稳之后再切到正式通知。这比直接上线然后反复调阈值要高效得多也保护了值班团队有限的注意力。这套做法本质上就是给规则引擎加了一层“预发布环境”——业务代码可以灰度告警规则同样可以灰度。6.2 权限和数据边界要前置设计雷达这种平台型工具一旦用起来各业务线都会想往里加数据。如果一开始没有权限和边界设计后期一定会乱。我们的原则是“数据提供方负责打标签数据消费方按标签取数”平台自身不修改各业务线上报数据的归属标签但是保留“越权提示”的审计能力。这样既保证了灵活性又能在出问题时有据可查。有一个比较实用的设计细节每个接入雷达的业务系统都对应一个接入配置包含业务线负责人、数据负责人、告警接收人三个角色。任何规则变更、数据变更都会通知这三个角色。刚开始大家觉得多此一举后来某次有团队误删了采集任务信息同步到位后问题10分钟就解决了大家才意识到这个设计多重要。6.3 自己和团队的时间投入要心里有数给想要复现这套系统的人一个时间参考第一阶段数据接入大概需要2到3周取决于有多少系统需要改造接入。第二阶段规则引擎开发2周左右这部分主要是设计规则表结构和评估逻辑。第三阶段控制台前端1到2周做一个够用的版本其实不难。第四阶段打磨稳定性持续进行每一步都会遇到真实的教训。最容易被低估的是采集器本身的稳定性。它是最贴近生产环境的部分一旦崩溃或资源泄漏影响面是所有下游。建议把它当成一个发布要求极高的生产服务来对待做好进程守护、配置灰度、日志回传和CPU/内存自监控。7. 后续扩展的思路PLFM_RADAR这套雷达目前已经在内部稳定运行了大半年在线故障的发现时间从过去的“用户反馈后半小时”缩短到“系统触发后3到5分钟”很多问题甚至还没影响用户就先被雷达拦下来了。对我个人来说这个项目最大的收获倒不是技术本身而是理解了“平台类工具”的建设节奏先想清楚要解决谁的什么问题再选型动手小步快跑地迭代比一上来憋大招稳妥得多。接下来我们计划给雷达加一个简单的“根因推荐”模块把历史告警和对应的处理记录沉淀成案例库当新告警发生时自动匹配相似的历史场景并推荐排查方向。这个事本质上不是算法问题而是数据积累问题——雷达已经跑了大半年案例数据够了后面就是顺理成章的事。如果你正打算做类似的东西我的建议是别贪大从最让你痛的那一个场景切入做一个能跑的最小闭环把它用起来再一步步往外扩。监控系统最怕的不是功能少而是没人看。让它真正成为团队每天都会打开的工具这套系统就算成功了一半。