2. 核心设计思路与方案选型
2.1 为什么不用商业监控方案,非要从零写雷达
在动手写 PLFM_RADAR 之前,我其实先纠结了一个问题:现在市面上成熟的监控告警系统太多了,Prometheus 全家桶、Zabbix、各种商业 APM 都是现成的,为什么还要自己折腾一套?
我的理由有三个。
第一,商业 APM 和开源全家桶解决的是“通用问题”,也就是“监控一切”的问题,但我当时需要的恰恰是“特定问题”的答案。平台团队日常最痛苦的事情不是没有监控,而是不知道用户的真实动作落在哪个环节。比如用户点了上传按钮,从请求发出到云端返回,中间经过网关、鉴权、配额、存储路由、对象存储,这条链路哪个环节慢?哪个环节正在悄悄失败?传统监控工具给的是机器维度的指标和链路维度的追踪,但一张表里几十个平台接口的真实健康度,反而要靠人肉一条条去对。PLFM_RADAR 从一开始就定位成“业务雷达”,只扫平台自身的平台域能力,不做大而全,只做深而准。
第二,维护成本的问题。商业 APM 和 Prometheus 全家桶的部署维护并不轻松,尤其是对于小团队,一套完备的监控体系通常要维护 Grafana、Prometheus、Loki、Tempo、告警组件、Agent 升级,还有一堆导出器和自定义 exporter。PLFM_RADAR 的核心思路是“轻”,一个进程、一个数据库、一组探针,定时采集指标并向自身推送,不依赖额外中间件,出问题的时候能自己说明白问题在哪。能少一个组件就少一个组件,这是我非常坚持的原则。
第三,自建雷达能让我拿到“完全可解释”的数据。商业方案的黑盒聚合模型,很多时候指标异常了,但我不知道这个数据具体是怎么算出来的。自己的雷达,每一个指标、每一次探测、每一条阈值规则,都是我亲手定义的,数据从哪来、怎么算、什么时候算,清晰可见。出现问题时我可以直接回溯原始请求,而不是先反过来猜指标含义。
2.2 雷达、探针、目标库:三个核心概念的拆解
PLFM_RADAR 的整体的结构,我用三个概念来组织:雷达、探针、目标库。这三个概念可以类比成真实雷达系统里的三个部件。雷达本体负责扫描和输出,探针就是雷达波束,目标库就是被扫描对象的状态记录。
雷达本体是系统的核心部分,负责调度所有探针周期性地扫描目标库里的目标对象,把探针的返回结果记录下来,同时根据阈值规则判断目标是否健康,最终输出一份可读的雷达报告。这一层不关心具体业务,只关心“你告诉我扫哪个目标、用什么方式扫、结果代表什么”。
探针是雷达的感知单元。每一条探针定义了目标对象的探测方式,最基础的探针类型包括 ICMP 探针、TCP 探针、HTTP 探针、功能探针等。以 HTTP 探针为例,它不仅仅是发一个 GET 请求看返回状态码,还会记录 DNS 解析耗时、TCP 建连耗时、TLS 握手耗时、首字节耗时和总耗时这些细节。功能探针则是真正贴近业务的方式,比如调用一个平台的 API 并且校验返回结构,通常用来验证鉴权、配额、对象存储等核心能力的真实可用性。
目标库就是被探测对象的清单。每个目标对象记录了这个对象的名字、所属分组、预期的状态码、期望的响应时间以及对应的探针类型。目标库的清单要覆盖平台前端接入域名、对象存储服务地址、消息队列集群、中间件服务地址,以及平台的核心外部依赖服务。
这三者的关系是:目标库定义雷达要干活的对象清单,探针定义了干活的具体方法,雷达本体定义干活的节奏和评价标准。每十分钟调度一轮,每论结果落库,每小时生成一次汇总雷达图。PLFM_RADAR 的定位在于,它盯的是“平台对外提供服务的真实可用性”,而不是某个具体服务器的 CPU 负载。
2.3 数据落库与指标体系的搭建思路
PLFM_RADAR 落地过程中,最容易让人踩坑的地方反而不是探测逻辑,而是数据落库和指标体系的组织。因为雷达每十分钟输出一组数据,一组数据包含几十个目标对象、每个对象多个指标,如果不提前设计好指标体系,数据一多就很难追踪到真正的问题指标。
我当时的做法是采用“探测任务、探测结果、当前状态”三层指标体系。探测任务表保存了每一轮任务的信息,包括轮次 ID、开始时间、结束时间、触发类型、结果摘要;探测结果表保存这一轮任务中每一条探针的详细结果,包括探针类型、目标地址、结果状态、耗时明细、错误信息;当前状态表则只保留每个目标对象的最新状态,因为这条表会在告警和雷达页展示时频繁使用。
这套体系的好处是三个层面之间的数据各司其职。挑问题的时候查当前状态表,那是“此时此刻发生了什么”;复盘的时候查探测结果表,那是“过去一段时间持续发生了什么”;趋势分析的时候查任务表,那是“整体轮次的稳定性如何”。
指标的计算也遵循“先落原始值、再算衍生值”的做法。原始值来自探针的直接结果,比如 HTTP 探测的返回状态码、响应时间、首字节耗时;衍生值则包括成功率、平均耗时、P95 耗时、故障时长等。衍生值全部在展示阶段计算,不在写入阶段计算,这样做的原因是雷达报告要支持按小时、按天、按周的维度查阅,而同一批原始数据在不同维度下算出的衍生值会有细微差别,保留原始值才能保证统计口径的一致。
3. 核心模块拆解与探针实现详解
3.1 探测器基类设计:雷达探针的通用骨架
所有探针类型都继承自同一个探测基类。这个基类定义了探针的通用行为,包括探测任务的执行流程、结果回传、超时控制、异常捕获。这里最需要注意的一点是超时控制,现实中探针挂了或者目标服务出问题的时候,拒绝响应是常态,如果没有严格的超时限制,一个探针就能拖垮整轮扫描。
探针基类的执行流程我设计成四个阶段:构造探测上下文、执行探测请求、解析探测结果、回传探测记录。构造上下文阶段会读取目标对象的基础信息,组装成探针需要的参数结构;执行探测请求阶段由具体子类实现;解析探测结果阶段处理返回值、异常和耗时数据;回传记录阶段把结果写入数据库。
超时控制我建议分三层来设置:全局探针超时、单次请求超时、整体任务超时。全局探针超时是单条探测任务的最大允许时间,通常设为 15 秒;单次请求超时是底层 HTTP 客户端的连接和读取超时,通常设为 5 秒;整体任务超时是整轮扫描的最大用时,通常设为 120 秒。每层超时都层层收紧,防止最坏情况发生时雷达自己也被拖死。
3.2 HTTP 探针与全链路耗时拆解
HTTP 探针是 PLFM_RADAR 里用得最频繁的探针类型。它不只是在目标地址上发一个 GET 请求看返回状态码,而是要把一次请求的完整链路耗时拆解开,这样当平台响应变慢时,我能知道慢是在网络层、在平台网关还是在上游依赖。
一次完整的 HTTP 探测,我会记录六个时间节点:DNS 解析开始时间、TCP 建连开始时间、TLS 握手开始时间、请求发送时间、响应首字节时间、响应结束时间。这几个时间点的差值,分别对应 DNS 耗时、TCP 建连耗时、TLS 握手耗时、上传耗时、服务端处理耗时、下载耗时。
有人会问,TLS 握手耗时不是都包含在 TCP 建连里面了吗?这个理解其实有误区。TCP 建连和 TLS 握手是两个独立的阶段,TCP 建连是三次握手,TLS 握手是加密协议协商。在网络环境复杂的情况下,区分这两个指标可以快速定位问题。比如之前我遇到过平台登录接口突然变慢,从雷达数据看 TCP 建连很快,但 TLS 握手耗时飙到了 800 多毫秒,最后排查下来是一个安全组件对证书校验逻辑有性能问题。如果不拆这些阶段,只看总耗时的话,根本定位不到这么深。
HTTP 探针还有一个细节容易被忽略,就是判定成功。并不是返回状态码 200 就一定算成功,对于某些平台接口来说,返回 302 重定向可能才是正常响应,返回 200 反而说明逻辑到了错误分支。所以探针的设计里把“状态码集合”作为可配置项,每条目标对象都可以定义自己期望的状态码集合,而不是写死一个 200。这一条细节让雷达的准确性提升很大,因为平台的很多资源类型接口需要按实际的语义来判定健康。
3.3 TCP / ICMP 探针:吃掉那 5% 的网络层假故障
HTTP 探针能覆盖大部分场景,但有一类故障仅靠 HTTP 是看不出来的,那就是目标服务“响应很慢但最终成功”,以及“TCP 层被拒但 HTTP 层没机会发请求”。这种情况在高并发平台场景里出现过多次,所以我额外实现了 TCP 探针和 ICMP 探针。
TCP 探针执行的核心动作是对目标 IP:Port 发起一次 TCP 连接,并记录建连耗时和连接结果。它可以用来探测平台下各类中间件端口、数据库端口、对象存储端口以及内部网关端口。网络层不通时,TCP 探针能比 HTTP 探针先发现故障,而且耗时更短、对业务影响更小。
ICMP 探针直接发送 ICMP 报文来监测目标主机的连通性。它的作用是帮助判断“目标服务所在网络节点的状态”。这里我想特别提醒一下,不要过度依赖 ICMP,因为很多云环境下 ICMP 包会被防火墙拦截,或被交换机限制,丢包率数据未必反映真实网络状况。所以在 PLFM_RADAR 中,ICMP 探针只用来观测网络节点层面的大范围连通性,不对它设置严苛阈值,避免出现雷达误报。
这三种探针分别覆盖了 HTTP 应用层、TCP 传输层、ICMP 网络层,合在一起形成了完整的探测视角。真实故障里,很多问题往往发生在某一层,如果只盯 HTTP 状态码,其它两层的假故障就很容易被忽略。
3.4 功能探针:直接拿业务能力来试“真”
如果说 HTTP 探针是扫“表面健康”,那功能探针就是扫“功能健康”。HTTP 探针能做的最多就是验证目标地址能响应、状态码正常、耗时在可接受范围,但它无法验证平台的业务平台功能是否真的可用。比如平台对外宣称支持单个文件上传,但后端存储服务的 Bucket 配置已经异常了,HTTP 探针看平台入口可能仍然是 200,毕竟网关层面是正常的,可用户实际上传就是失败。
功能探针解决的就是这个问题。它的设计思路是“以核心用户的视角,真实地执行一次业务动作”。以对象存储功能为例,功能探针会去执行一次小文件的临时写入、读取、校验、删除动作。一次性执行完写入、读取、校验、删除四个步骤,任何一步失败,都能说明平台的对象存储通道存在隐患。这比单纯探测“连通性”有说服力得多。
功能探针的真正难点不在于写探针本身,而在于规划探针执行的动作不能影响线上业务。踩过一次的坑是:功能探针在上传文件时使用了线上正式生产的账号与命名空间,结果造成线上数据出现了一个意外的测试文件。后来我优化成使用专用的雷达探测账号与独立的隔离命名空间,这样不管探针执行什么动作,都不会污染线上的真实数据。这个经验特别重要,尤其在用雷达检测有状态服务的时候,一定要保证探测动作具备“只读或自清理”的特性。
4. 雷达调度机制与报告视图设计
4.1 调度节奏:十分钟一轮,为什么是这个频率
雷达要定期执行扫描任务,而扫描频率直接决定了两个事情:故障发现速度和系统自身开销。PLFM_RADAR 默认的扫描频率是每十分钟扫描一轮,有人可能会觉得十分钟太慢了,实时告警不应该是分钟级甚至秒级吗?
我说一下这样设计的理由。最核心的原因是关于探针模拟的目标用户行为,平台的绝大多数异步类业务,在正常状态下本身就是分钟级的反馈时延。用户提交一个任务后,通常要等一两分钟才能看到处理结果。如果雷达每 20 秒就去“真实地执行”一次平台操作,这批探针本身就会对平台带来不小的额外压力,划不来。
十分钟一轮还有一个好处是可以拿到比较稳定的统计样本,不容易被偶发波动带偏。你设成秒级扫描,反而会被网络抖动干扰,频繁产生告警。十分钟一轮,每轮 120 秒内完成所有目标扫描,一小时下来就是 6 轮,一天的完整数据就是 144 轮。这个规模的数据对于做趋势分析来说已经足够稳了。
当然,雷达的调度周期针对特定场景也允许配置。例如平台的核心登录链路和上传链路,单独配置了更高频的扫描任务。低频的全量扫描兜底全平台,高频的重点扫描盯核心链路,这是调度设计的层次感。
4.2 重试调度、失败补偿与并发控制
调度机制设计上最容易出问题的阶段是在任务重试阶段。网络抖动导致单轮任务中个别目标探测失败,是雷达用久了必然会遇到的情况。如果探测失败后马上重试,成功率低、重试开销大,还会影响整轮任务的完成时间。所以我的做法是,把失败目标先记录为“本轮可疑”,等整轮任务完成之后,再从可疑列表中挑选目标进行第二轮补充探测。
补充探测最多只做一次。如果补充探测依然失败,就把该目标的探测结果标记为异常,并进入报告渲染阶段。这样的做法比“失败了立刻重试”稳定得多,因为能避免因为一次网络抖动就在日志里刷一堆失败记录。
并发度是另一个需要注意的点。我一开始用无并发约束的协程池去批量执行探测,很快发现个隐患:雷达的并发探测本身就可能对平台网关产生连接压力,尤其是几百个目标同时发起请求的时候,平台侧可能把雷达误判为异常流量。后来调整为按目标分组的顺序扫描,每组内部再并发,并发度限制在 8 个以内。这样每一轮扫描的峰值 QPS 都控制得稳稳的,不会影响平台本身。
这里补充一个经验值:扫描目标的并发度,建议不要超过平台入口网关并发能力的 2%。如果你不确定平台的并发能力,就从并发度 4 开始压测几轮,看探测结果里的失败率和耗时有没有明显抬升,再逐渐加并发度。
4.3 雷达报告视图:从“健康状态矩阵”到“趋势曲线”
PLFM_RADAR 把探测结果可视化成雷达报告,报告上可以看到三个核心视图:目标健康状态矩阵、瞬时状态概览、健康趋势曲线。
目标健康状态矩阵是最直观的视图。所有目标对象以组为单位排列,每个目标格子的颜色代表当前状态,绿色是健康,黄色是注意,红色是异常。这一张矩阵基本是平台的“随时体检报告”。围观这张矩阵可以做很多事,比如某一天平台某个接口偶尔变慢,矩阵上就能看出黄点在慢慢扩散。
趋势曲线视图是我最常用的一个。它绘制每个目标对象的历史健康趋势、可用耗时、成功率等指标。判断一个问题是不是偶发问题的关键数据就在趋势图里,单次红色异常也许只是抖动,连续 30 分钟的成功率下降曲线,才是需要去查的真实故障。在对外向管理层同步故障成因时,我也习惯直接用趋势曲线来佐证问题发生的起止时间,这比靠嘴说清楚得多。
真正能体现雷达报告价值的,是它对监控数据的二次聚合。同一段时间内,雷达会把每次探测的耗时、成功率、失败原因都归纳成摘要,并在报告层面给出一个“平台整体的健康评分”。分数是一个 0 到 100 的标尺,主要根据目标异常数量、失败持续时长、整体趋势来算。虽然只是一个简单评分,但在和运营团队同步平台状态时,这种一目了然的分值反而是最好用的语言。
5. 雷达告警策略与阈值模型
5.1 阈值设定原则:宁可漏报,不可误报
告警策略是整个雷达里最容易让人纠结的环节。刚开始做的时候,我的调整心态是越灵敏越好、什么都想告警,结果就是值班群里每天都在喊“有异常”,但大部分都是噪音。用户不会因为你报警报得勤就觉得你认真负责,反而会因为误报太多而对雷达失去信任。
所以我在 PLFM_RADAR 的告警策略里,引入了一个基本原则:宁可漏报,不可误报。具体落地上,阈值不会拍脑袋定出一个绝对值,而是基于真实历史数据来推导。先观察 20 天的历史数据,计算出每个目标对象平均响应耗时和标准差,然后把阈值的基准线设成平均值加 N 倍标准差。N 的取值按目标的重要程度来定:核心链路取 3,非核心链路取 5。
这样做的好处是,每个目标的告警阈值都是动态适配的。有的对象天生响应慢,平均值就有 800ms,阈值如果硬定成 300ms 的话一天能报警上百次。用 N 倍标准差的方式推导阈值,天然符合该对象的实际运行特征,显著降低了雷达噪声。
5.2 多级告警与告警降噪机制
雷达告警分为三级:橙色预警、红色严重、深红紧急。橙色预警对应单轮探测失败或响应变慢,表示需要关注;红色严重对应连续 2 轮失败或耗时超阈值持续 20 分钟,表示需要处理;深红紧急是核心链路连续 3 轮失败或连接不可用,必须立刻介入。
多级告警避免了“出一张告警就拉响全城警报”的尴尬场景。普通故障先记为橙色预警,如果后续恢复正常就把状态标记为“已恢复”,不打扰值班人员。只有超过设定持续时才升级到红色或深红,整个上报过程依据连续失败次数进行计算,而不是靠一轮的数据下结论。
告警降噪还有一个机制:消息聚合。多条目标在同一时段内同时失败的情况,雷达会合并为一条聚合告警,而不是分别发 20 条告警。比如平台某条健康检查链路依赖同一个上游节点,这个上游一抖动,所有目标几乎同时失败,如果每条都发告警,值班群瞬间就被刷屏。聚合后只报一条,附带上受影响目标的列表,大家能一眼看出问题波及的范围。
5.3 告警触达:推送、静默与值班轮转
告警的触达方式我采用企业通知平台的 Webhook 机器人,通过机器人把告警消息推送到值班群。每条告警消息里包含雷达名称、异常目标、异常指标、当前值、阈值、异常时间段和探测报告链接。链接指向的是雷达报告的详情页,点进去能看到完整的数据,非常实用。
静默机制对告警体验影响极大。平台的例行维护窗口、版本的灰度发布期间,目标出现暂时性抖动,实际上是预期内的。如果没有静默机制,雷达就会在每次发布时误报一轮。所以我在雷达里加了一个维护窗口配置,配置之后,该时间段内的异常只记录不推送告警。这个功能在实际使用中帮我减少了很多无意义的告警噪音。
值班轮转机制我后来也加上了。平台团队几个人轮流值班,如果每组人员的告警都推给所有人,也很容易疲劳。配置轮转表之后,机器人会自动按值班表切换接收人。这虽然不算一个大功能,但实际体验提升非常明显。毕竟,系统能不能留住人,靠的不是完美架构,而是用完还想继续用下去的顺畅感。
5.4 从指标到告警通知的完整流转链路
哨兵雷达从探测结果到告警通知,完整走通一条链路的处理逻辑是这样的:调度器触发一轮扫描之后,所有探针结果入库。状态判定器读取本轮结果,结合历史结果,判断目标是否达到告警条件。如果达到,就进入告警生成器,根据目标的重要程度生成对应的告警级别,同时检查维护窗口,判断是否推送。最后通过通知组件推送到对应值班人。
这个流程里我认为最有价值的一点是状态判定器设计的去中心化逻辑。判定器不依赖全局状态,而是按照目标对象逐个判定。比如平台的核心链路 D 失败,这不会影响核心链路 C 的状态判定,两者之间的事件互不干扰。这个设计让排查问题的过程变得非常清晰,只要看单个目标对象的状态流转记录,就能完整还原故障过程,不用去推断全局状态。
6. 雷达落地实录:实施步骤与经验复盘
6.1 第一版雷达的目录结构与功能清单
PLFM_RADAR 的代码结构非常适合用目录来理解。雷达程序根目录下,按功能拆分了几份核心文件:主程序入口负责启动调度器和各定时任务,探针模块集合所有探测器的实现,目标库维护平台的目标清单读取和写入接口,状态判定器处理探测结果的判定逻辑,报告引擎负责生成雷达报告和趋势曲线数据,通知模块处理告警推送。
第一版雷达的功能清单,我把它拆成五类。扫描探测类功能包含定时执行全量扫描、定点执行重点链路扫描、按需手动扫描指定目标;目标管理类功能包含目标清单的增删改查和分组管理;报告展示类功能包含实时状态矩阵展示和趋势曲线;告警管理类功能包含告警级别设置、维护窗口配置、告警推送记录查询;统计分析类功能包含成功率统计、耗时趋势统计和故障时长统计。
这些功能从第一版上线就没删过。回头看这个设计,它们的共同点在于每一个功能都对故障排查有直接的实际价值,没有一个是“锦上添花”的摆设功能。雷达这种工具,功能越聚焦,越贴近一线的排查需求。
6.2 和真实用户流量配合:构建双通道验证
雷达虽然监测的是平台健康度,但它本身和真实用户流量之间是盲区关系。雷达探测的是一条链路,真实用户的体验是另外一条链路。这在实践中出现过不少问题,比如探测链路一切正常,但用户在论坛上疯狂反馈平台打不开,原因可能是骚扰流量被网关限了策略,而雷达的探测 IP 不在限制范围里。
所以后续我给雷达补了一个“旁路流量感知”的机制。雷达探测之外,还接入了一组平台入口的访问日志实时分析,提取核心接口最近 5 分钟内的真实请求状态。通过访问日志得到的数据,不会替代雷达探测数据,但会和雷达探测的结果放在一起,形成一个双通道联合判定的状态。只有雷达探测、真实流量两个通道都判定异常时,系统才触发告警推送,单通道异常先记录为观察态。
这样设计的效果非常明显,告警的准确率上升了不少,还减少了因为雷达自身探测过于“理想化”而遗漏真实故障的问题。比如平台对象存储的某个节点确实退化了,雷达探测可能还通,但真实流量已经出现大面积的 503。通过双通道聚合才能把这个故障捞进告警范围。这一条经验我认为是做雷达类项目最关键的一条。
6.3 一次真实故障的排查复盘:雷达如何帮我定位
有一个印象很深的故障,可以从头到尾复盘一下雷达在其中的作用。当时平台的登录接口出现了偶发的缓慢现象,用户在晚高峰反馈“登录转圈很久”,但所有的基础监控指标都正常,服务器负载不高、网络带宽不饱和、数据库慢查询没有明显上升。如果没有雷达,这个问题极难排查,只能靠猜。
雷达在故障期间的数据是这样的:登录接口的 HTTP 探测成功率为 100%,状态码全部正常,但服务端处理耗时从平时的 180ms 突然拉高到 1300ms,持续了一段时间。这个数据说明平台入口没有断但业务处理链路在变慢。通过雷达的趋势曲线定位到故障时间窗口后,我去翻了登录链路接入层的请求日志,发现慢请求集中指向一个缓存热 key,热 key 的查询在高峰期出现了严重的锁竞争,导致处理耗时飙升。
这次排查之所以能完成,雷达最重要的贡献就是给了准确定位的“时间窗口”和“耗时问题层”。如果没有雷达把异常行为约束到具体的半个小时,没有把问题层次锁定到处理耗时的异常,按传统排查逻辑很容易先去查服务器性能,去查数据库,绕一个大圈还不一定有结果。雷达的价值,就是帮你在茫茫运维数据里锁位置、压时间、提供可靠候选方向。
6.4 雷达上线前后,值班体验的变化
雷达上线前后,平台团队值班体验的变化,我用一张对比表来说明。
上线前,排查平台问题的流程基本是:群里有用户报障、值班同学用命令行看负载看日志、联系各个团队专家一起在线讨论按钮。
缺少主动发现,总是在用户发现问题之后才被动响应。故障定位基本靠人脑经验,经验不足的人无从下手。上线后,雷达主动探测,很多问题在用户感知之前就已经捕获。能给到具体的时间窗口、目标对象、异常指标和响应耗时分布,顺着这些数据了解问题很快,甚至不用开讨论组。
最有体感的变化,是告警从“吓一跳”变成了“知道要做什么”。雷达给出的告警不是冷冰冰一行字,而是完整的诊断信息。值班同学收到告警不再紧张,因为下一步动作已经被雷达的结果牵引着,直接看报告点链接就能定位到目标详情页验证。
7. 踩坑实录与排查技巧总结
7.1 探测数据污染:不要把测试数据混入业务数据
功能探针最大的隐藏风险是数据污染。雷达探针在执行功能测试时会产生测试痕迹,而且探测数据记录本身如果和业务数据统计混在一个表,时间长了也会影响业务报表和监控口径。
这里推荐两个做法。第一,数据库层面把探测数据放在独立的数据库中,和业务库完全隔离。第二,在目标对象的设计里,把测试账号、测试文件、测试命名空间都集中在专门的“雷达测试域”中。比如文件上传测试,永远上传到特定的 radartest bucket,文件名带 radar 前缀,并设置生命周期规则自动清理超过 3 天的文件。这个细节看起来是小事,但能避免很多尴尬。
第二个容易被忽视的是“数据结果的可重复性”。地址或目标对象一旦变更,历史探测数据的口径就不一致了。雷达如果后续要给目标改地址,务必确认报告同步呈现有效时间区间,不能新老地址数据混在一起做趋势分析。
7.2 目标库维护:健康的目标清单带来自动的健康报告
目标库的维护质量直接影响雷达的报告质量。目标库里的目标如果过多过杂,雷达会变成“告警噪音发电机”;如果过少,雷达又看不到全貌。做得好的目标库应能覆盖三类目标:用户核心链路上的关键入口、平台各个基础设施服务的健康探测、核心外部依赖的可用性。
目标库里的每个目标,至少要有分组、探针类型、探测周期、目标地址、判定规则、软阈值、硬阈值和负责人信息。一条目标对象的数据不全,告警出现时都无法准确协同到人。负责人信息是我强烈建议要加的字段,一条目标异常时执行能根据负责人直接定位。
目标库不是一次建好永不更新的。每个新版本上线、每个依赖变更、每个网关策略调整,都要跟着更新目标库。雷达的探测质量依赖于长期、持续的目标库维护习惯,这个不需要极高技术含量,却是雷达项目能不能长期玩下去的胜负手。
7.3 雷达自身的反脆弱:避免监控系统成为被监控系统的单点故障
雷达能稳定运行,比雷达能抓问题还重要。如果你的雷达挂了,你就失去了所有主动发现问题的手段,平台成了瞎子。所以雷达自身的可用性设计,不能只看探测效率。
雷达程序本身建议以守护进程方式常驻,配合系统服务进程做开机自启和异常拉起。雷达的配置尽量简化,但运行状态本身必须可见。我给雷达加了一条基础自检机制:每三分钟检查一次雷达自身进程状态,如果出现异常就自主重启并把告警发给管理员。这条机制保障了雷达的长期运行率。
数据库后端和雷达本体分离也值得注意。后端数据库建议单独部署,避免数据库负载和雷达本体运行互相干扰。还有一点,雷达探测目标时如果目标库里有大量失效地址,探针会一直收到大量错误,导致探测日志暴涨。所以周期性的目标库“体检”也很重要,要清理长时间不可达且已确认废弃的目标对象。这能让雷达数据库的体积维持在稳定水平。
7.4 常见问题速查表:新手必收的故障对照清单
我在调整和上线 PLFM_RADAR 的过程中,遇到的各类问题,整理了一份速查表,分享出来。
如果你发现所有探测全部失败,首先要看雷达所在网络到目标组网的连通性,大概率是雷达自己的出口网络受限。如果你发现偶尔单点失败但重试成功,多半是瞬时网络抖动,建议告警策略里增加重试判定。如果你发现耗时稳定变慢但服务器指标正常,可能问题在链路中的网关或依赖服务,去查增长耗时所在的阶段。如果发现探测结果一直超时,则可能是探针配置的连接超时时间太短,或目标服务的连接队列满了。如果你发现某些目标频繁产生误报,建议调整对应目标的标准差倍数和连续轮数,而不是全局降低所有目标的灵敏度。如果你发现告警很多但用户没有反馈,先排查是否是目标库中有很多“无效目标”或开启了过于松的阈值设置。
在设置探测阈值时,我给新手的建议是:前两周不要开启自动推送告警,先把雷达放在“影子模式”下运行,只记录数据不推送告警。两周后再去复盘记录,观察哪些目标出现过异常、异常持续了多久,根据这段时间的真实数据去反推阈值设置,再开启告警推送。直接把阈值定得死死的,大概率会在上线第一周就被误报折腾到怀疑人生。
8. 从雷达 1.0 到雷达 2.0:后续可扩展的方向
8.1 数据可视化增强
雷达 1.0 的基础报告已经能用,但可视化层面还有很大的扩展空间。当前的目标粒度健康矩阵和趋势曲线已经具备了整体概览能力,如果能叠加一个按时间段比对的视图,就能在同一屏幕看到任意两个时间窗口的平台健康度对比,处理“今天是否比上周某天差”这类问题就会轻松很多。
另一个方向是拓扑视图。平台的核心链路往往是多层依赖关系,比如平台入口网关依赖鉴权服务,鉴权服务依赖用户中心,用户中心依赖基础数据库。当前的雷达把目标当成相互独立的对象来探测,如果把这些目标按照依赖关系用拓扑图串联,一条故障告警出现时,你就可以直接从拓扑图上看到故障扩散路径,这比看一堆孤立的探针结果要直观得多。
8.2 智能异常检测
雷达 2.0 的规划里,最想做的就是叠加一些智能异常检测能力。当前雷达告警还是依赖固定的阈值规则,阈值上限确实够用,但问题在于面对平台流量周期变化的时候,阈值有时候会显得僵硬。比如平台在每天凌晨的流量低谷期,探测耗时低而稳定;在晚高峰的时候,平台的偶发抖动对比平时会变大,但固定的标准差阈值并没有感知这种周期性差异。
用 7 日滑动的历史数据去做动态基线,计算当前值相对于动态基线的偏移程度,就能自然的适配不同时间段的不同特征,减少误报又保住重点异常。
8.3 与发布流程集成
雷达的告警数据可以把价值进一步扩展,接入发布流程就是下一步的计划。比如平台的版本在灰度发布时,雷达可以自动执行一轮重点链路的增量扫描,并在发布后的一段时间里高频关注受发布影响的目标对象。如果雷达发现发布之后出现持续性的成功率下降或耗时上涨,就能自动阻止发布流程继续推进,甚至可以联动触发快速回滚。
这是从“监控工具”走向“平台质量保障基础设施”非常重要的一步。雷达不再是观察问题的窗口,而是治理平台质量时能主动参与动作的保障系统。个人觉得,这才是雷达类项目的真正终点,把观测、分析、告警、联动全部串在一起,成为平台内部的“自愈环路”第一根支柱。
PLFM_RADAR 这个项目从零开始到现在逐步稳定运行,一次次帮助我发现真实问题。我最大的体会是一个好雷达,不在于技术多复杂,而在于它能不能真正贴合平台的运行特点和团队的协作习惯。技术选型永远有更花哨的方案,但能让你每天安心打开看几分钟、出了事第一时间给出线索的雷达,才是真正解决了疼点的雷达。如果你准备给自己负责的平台也做一套,建议踩稳我的步骤,从一个小目标清单开始,跑通一轮完整探测,再逐步扩展目标库和告警策略,最终它一定会成为你平台稳定运行过程中离不开的那双眼睛。