ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

从传感器到告警中心:监控链路搭建的选型、细节与踩坑实录

从传感器到告警中心:监控链路搭建的选型、细节与踩坑实录 做监控这块算下来也有几年了。从最早在服务器上装个 cacti 看流量到现在一套体系里同时跑着 Prometheus、Zabbix、夜莺还有几块自己用 STM32 搓的嵌入式采集板越来越觉得监控不是一个工具的事而是一条完整的链路。这个月正好赶上四个监控项目同时发版从车间里的温湿度采集到 Windows 服务器上的 TCP 连接数再到 K8s 集群资源和 NPU 利用率最后全部汇总到统一告警中心链路算是真正跑顺了。这篇文章想把这条链路的搭法、细节、坑和排查思路都记录下来给正在搭监控平台的朋友一个可参考的样本。1. 四个项目组成一条完整监控链路方案选型与整体设计1.1 为什么是四个项目链路里没有“万能工具”很多人一开始接触监控会下意识地去找一个“开箱即用的监控平台”希望装一套就能解决所有指标。但实际跑过一段时间就会发现监控这条链路上每一段的诉求完全不同单一工具很难全包。我在这次发版里同时处理了四个项目每个对应一段不同的监控场景项目A是基于 Prometheus Grafana 的云原生监控平台负责 K8s 集群、业务容器以及边缘机器上的 NPU 资源监控。项目B是基于 Zabbix 的传统基础设施监控覆盖几十台 Windows 和 Linux 服务器重点做了 Windows 服务器 TCP 连接数监控。项目C是夜莺监控平台定位是统一告警中心把 Prometheus 和 Zabbix 的告警收拢到一起再通过 webhook 推到企微群。项目D是嵌入式环境监控系统基于 STM32 采集食用菌栽培车间的温湿度、CO2 浓度和光照强度数据一路透传到监控中心展示。四个项目在同一天发版纯粹是计划撞到一起但回头看反而是好事它逼着我把整条链路从末端传感器到最终告警通知完完整整捋了一遍。链路里没有万能工具每套系统都有自己最舒服的位置关键是想清楚它们之间的边界。1.2 监控链路的五层拆解采集、传输、存储、展示、告警我自己习惯把监控链路拆成五层这次四个项目正好覆盖了全部五层。第一层是采集层负责从设备、系统、应用里拿到原始指标包括 STM32 板子上的温湿度传感器、服务器上的 Zabbix agent、K8s 里的 node-exporter 和 kube-state-metrics。第二层是传输层负责把数据从采集点送到存储端常见的有 SNMP、HTTP/HTTPS、gRPC、MQTTZabbix 走自家 agent 协议Prometheus 走 pull 模式抓取。第三层是存储层时序数据一般落在时序数据库里Prometheus 自带的 TSDB 在很多场景够用数据量大时可以接 VictoriaMetrics 或 Thanos。第四层是展示层Grafana 负责把散落的指标变成看板。第五层是告警层Alertmanager 和夜莺负责把异常变成一条条可处理的通知。这五层听起来很简单但每一层都有自己独立的坑。比如采集层的频率设得太高传输层又没做缓冲数据到了存储层就可能丢失展示层只做了美观没做语义告警层的目标就变得不清晰。如果一开始就把链路分层想清楚每个项目各管一段后面排查问题会轻松非常多。1.3 选型逻辑Prometheus、Zabbix、夜莺、自研各管哪一段这次选型不是我拍脑袋定的而是根据场景特点来的。Prometheus 适合云原生和动态环境因为它有服务发现K8s 里新增一个 Pod 后可以自动抓到新 target。Zabbix 适合传统服务器和网络设备它的模板体系非常成熟装个 agent 就能把 CPU、内存、磁盘、网络这些指标全部采集上来而且主动/被动模式在跨网段场景下很好用。夜莺监控的核心价值是告警统一。它有比较完整的数据源管理能力可以把 Prometheus、Zabbix、甚至云监控的告警汇聚到一个入口再用一套通知规则发出去避免“每个监控系统都在群里刷屏”的情况。嵌入式环境监控则是 Prometheus 和 Zabbix 都替代不了的。车间现场的温湿度传感器、CO2 传感器需要贴近物理环境部署延迟要低功耗受限用 STM32 做端侧采集最合适再通过 MQTT 把数据推给网关网关再转换成标准 HTTP 接口让监控平台消费。四个项目各管一段既有重叠又能互相补充链路才算完整。2. 核心细节解析与实操要点2.1 Prometheus Grafana 配置指导抓取频率、标签规范与告警规则Prometheus 部署起来不算难真正磨人的是抓取频率和标签规范。部署 Prometheus 监控 K8s 时node-exporter、kube-state-metrics、cAdvisor 是三个基础 exporter对应机器指标、资源对象指标和容器指标。还要注意 metrics-server 只提供 resource metricsPrometheus 要想拿到全量能力最好把上述三个都部署齐。抓取频率我这里没有全部用默认的 15 秒。常规指标比如 CPU、内存是 15 秒抓一次业务关键指标我会单独开一个 scrape_config用 5 秒间隔抓取像 NPU 利用率这种变化快的指标也建议高频抓取否则曲线会丢掉峰值。低频指标比如磁盘使用率30 秒到 60 秒一次完全足够没必要所有 target 都保持高频抓取。scrape_configs: - job_name: k8s-nodes scrape_interval: 15s kubernetes_sd_configs: - role: node relabel_configs: - source_labels: [__address__] target_label: instance - job_name: npu-exporter scrape_interval: 5s static_configs: - targets: [192.168.1.20:9100] labels: env: edge告警规则里我最容易犯的错是忽略for参数。没有for的规则会一抖动就报警加了for: 2m之后指标需要持续异常 2 分钟才触发告警能过滤掉大量瞬时抖动。同时还要注意 PromQL 里 rate 和 irate 的区别算 CPU 使用率用 rate(1 - cpu_idle) 更平滑算瞬时突发用 irate 更灵敏看告警规则建议以 rate 为主。Grafana 看板配置指导这块我会把经常看的指标做成独立变量比如节点选择、命名空间选择这样一块看板可以复用给所有环境。Panel 的阈值颜色也是排查问题的重要辅助不一定非要把绿色当成“健康”根据指标语义去配色比如磁盘剩余空间剩 10% 时直接标红比一张默认配色的面板更实用。2.2 Zabbix 监控 Windows TCP 连接数的两种落地方式Zabbix 监控 Windows 服务器 TCP 连接数很多人第一反应是用 netstat 命令然后靠文本解析。这个思路能跑通但有几个坑netstat 的输出格式在不同 Windows 版本上不完全一致中文环境下命令输出还可能带编码问题解析脚本很容易翻车。我这边实测下来更稳的是用 PowerShell 的Get-NetTCPConnection对象化输出不依赖文本结构。我最终实现的方案是在 Zabbix agent 的自定义配置里加一个 UserParameter通过 PowerShell 统计处于指定状态的连接数。比如要监控 SYN_SENT、ESTABLISHED、TIME_WAIT 这些状态脚本先调用 Get-NetTCPConnection按 State 分组计数然后输出成key value格式Zabbix 直接就能采集。$states Get-NetTCPConnection -ErrorAction SilentlyContinue | Group-Object State $states | ForEach-Object { Write-Output (tcp.state[{0}] {1} -f $_.Name, $_.Count) }对应的 zabbix_agentd.conf 配置UserParametertcp.state[*],powershell -NoProfile -ExecutionPolicy Bypass -File C:\zabbix\tcp_state.ps1监控项键值写成tcp.state[ESTABLISHED]就行。需要注意 PowerShell 脚本执行策略如果没放开会直接采集不到另外 Zabbix agent 如果是作为服务运行的默认跑在 SYSTEM 账户下网络接口信息一般都有权限读但脚本路径和日志路径要注意权限问题。比较坑的是 Windows 防火墙默认会拦掉 Zabbix agent 端口在 agent 测试时一定要先加放行规则。2.3 夜莺监控多数据源接入与告警收敛夜莺监控解决的核心痛点不是“能采多少指标”而是“告警到底由谁来管”。这次发版我把它作为统一告警中心Prometheus 和 Zabbix 的告警都往这里汇。夜莺接入 Prometheus 比较简单在数据源管理里配置一个数据源填上 Prometheus 的 HTTP API 地址即可。它支持直接使用 PromQL 写告警规则所以原来写在 Alertmanager 里的规则可以平移过来不用重新造一套语法。Zabbix 这一侧夜莺可以通过 webhook 接收 Zabbix 发过来的媒体告警也可以反过来调 Zabbix API 拉取问题列表。我这边因为 Zabbix 的历史告警格式比较乱选择让 Zabbix 通过脚本把告警转成标准 JSON 推给夜莺再统一静默和抑制。告警收敛是我这次最看重的部分。没有收敛之前同一个故障会同时从 Prometheus 和 Zabbix 各发一条告警再加上关联指标全告警群里一下就刷屏了。夜莺的告警规则里可以设置分组把同一个实例的多个指标打成一条告警事件同时可以通过静默规则屏蔽维护窗口内的告警比如发布期间对目标机器主动静默两小时。另一个很容易被忽略的点是时间窗口。夜莺的告警规则需要配置for或者持续时间和 Prometheus 的for是同一个道理主要是避免瞬时抖动误报。设置太短容易被骚扰设置太长又会导致故障感知太慢具体值需要根据业务容忍度逐条调整。2.4 嵌入式环境监控STM32 采集与上行链路嵌入式环境监控这部分很多人会问为什么不直接用现成的“物联网监控”设备而是自己用 STM32 搭。原因很简单项目现场是食用菌栽培车间传感器需要长期固定部署温湿度和 CO2 数据要求低误码、低延迟地上报还要和现有的监控链路统一展示。市面上的物联网设备大多有自己的云平台想把数据纳入自有监控体系反而要多一道取舍不如直接自研。硬件选型上主控用 STM32F103 就够用传感器选了 SHT30 测温湿度MH-Z19B 测 CO2 浓度光照用 BH1750。供电用 DC-DC 稳压模块通信先用串口接一个 ESP8266 模块做 WiFi 透传发给车间网关。上位机用 Python 接收 MQTT 消息再以 Prometheus exporter 的格式暴露 HTTP 接口这样 Grafana 不需要额外写插件就能直接拉数据。用 STM32 做采集有个特别容易踩的坑I2C 时序不稳定。传感器在某些型号上会和主控 I2C 时序不兼容经常出现读回的温湿度偶发跳变。我最后给每个传感器延长了上电延时并且在读取数据的时候加了 CRC 校验数据异常时直接丢弃重读才把误报压下去。嵌入式端的数据稳定性是整条链路的地基如果端侧采集本身就有抖动上层 Prometheus 规则写得多漂亮都会误报。3. 实操过程与核心环节实现3.1 同日发版四个项目的排期、顺序与回滚预案四个项目同日发版排期上有个基本原则先底层后上层先旁路后主路。我当天的发布顺序是嵌入式环境监控先升级固件和网关程序因为它影响的是采集源然后发 Prometheus 和 Zabbix 的采集配置变更这个阶段告警规则还是旧的只采集不告警最后发夜莺的告警规则和通知路由确认前面数据都正常后才打开告警。发布顺序错乱会导致很经典的故障比如 Prometheus 的配置先改了但 Grafana 看板还没更新变量展示出来的标签对不上或者告警规则先发了但采集端还没有数据触发一堆“数据缺失”告警。所以我排了一张时间表每个项目预留 15 分钟冒烟时间。时间段项目操作验证方式09:00-10:00嵌入式环境监控烧录固件、更新网关查看 MQTT 收到数据并落库10:00-11:00Prometheus更新 scrape_config、exporter查询 target 状态和指标曲线11:00-12:00Zabbix更新 agent 配置和模板验证 TCP 连接数监控项有数据14:00-15:00夜莺接入数据源、发布告警规则发送测试告警并确认消息接收回滚预案方面每个项目的配置都打了版本标签。Prometheus 的配置文件在改动前先备份到 GitZabbix 模板导出为 XML 后存档嵌入式固件保留了上一版 bin 文件出问题 10 分钟内可以全部退回去。监控系统的变更最怕偷偷改所有配置必须留痕。3.2 统一监控中心接入Grafana 与夜莺的数据源配置统一监控中心有两个入口一个是 Grafana 做展示层一个是夜莺做告警层。Grafana 这里的数据源不止一个我同时配了 Prometheus、Zabbix 的 MySQL 和模拟环境的数据 API。用 Prometheus 数据源时URL 指向 Prometheus 服务浏览器直接访问不一定通需要在 Grafana 的配置里允许服务端访问子网。夜莺接入 Prometheus 时数据源 URL 同样只能填内网地址。这里有个坑夜莺的采集引擎会直接拉取数据源上的指标如果 Prometheus 的http接口开了认证需要把 token 配到数据源配置里。如果 Prometheus 和夜莺部署在不同的网段还要检查防火墙的入站规则别只盯着 Grafana 看板连通了就以为万事大吉。统一看板我建了一个“监控中心总览”顶部是嵌入式车间的温湿度、CO2 实时值中间是 K8s 集群节点的 CPU 和内存底部是 Windows 服务器的 TCP 连接数变化旁边用状态灯标识告警级别。看板配置的关键是变量联动比如选择车间后温湿度面板的数据源自动切换对应区域这个需求在 Grafana 里用-- dashboard变量模板就能实现。3.3 跨网段采集与链路聚合eth-trunk、路由与安全组监控链路一旦跨了网段问题就变得麻烦。车间采集板在一个二层网络服务器在另一个 VLAN监控中心在第三个网段。嵌入式数据走 MQTT 到网关后由网关 IP 上报这在网络层看起来是网关到监控中心的单点传输但 Prometheus 的 pull 模型需要从监控中心主动访问各 target如果 target 分布在多个网段必须保证监控中心到这些网段的 TCP 端口可达。eth-trunk 链路聚合这部分原本是为了解决交换机到监控服务器之间带宽瓶颈问题。两条千兆物理链路绑成一个逻辑链路既增加带宽又能做链路冗余。配置链路聚合时最容易翻车的点是两端协商模式不一致一边是静态 LACP 一边是手工聚合接口状态会显示 up 但流量不均甚至不通。建议两端都用 LACP 主动模式物理链路故障时切换速度比 STP 快得多。网络层面还有一个我经常忽视的点Prometheus 抓取超时。跨网段抓取时如果中间有多层 NAT 或防火墙做会话管理抓包响应时间可能超过默认的 10 秒超时。我这次把每个 target 的抓取超时单独调大并且给必要的端口单独开白名单尽量不依赖“监控中心能 ping 通”来推断抓取就能成功。3.4 监控数据存储与容量治理保留周期、压缩与降采样四个项目合流之后数据量上涨比我预想的快。Prometheus 默认保留 15 天这次有一个业务指标需要保留 30 天。如果直接调大--storage.tsdb.retention.time磁盘占用会明显上升。这里有个容量估算公式单个指标每小时大概占用 0.4KB 到 1KB一万条 series 15 天大约需要 160GB 到 380GB。如果每秒抓一次容量需求会翻几倍所以高频抓取只用于少量核心指标。我这边用到的存储策略是组合拳。高频指标只保留 7 天基础指标保留 30 天再通过 Prometheus 的 recording rule 做降采样把原始指标按照 5 分钟、1 小时聚合成新指标新指标再存进独立的 TSDB。实测下来磁盘占用从原来的 320GB 降到 180GB 左右30 天的长趋势依然能查询到只是精度从 15 秒降成 5 分钟。Zabbix 的历史数据也存在 MySQL/PostgreSQL 里默认情况下面是全量保留数据量大时可以直接改 housekeeper 的保留天数同时启用趋势表来保留小时级数据。监控系统的存储没有银弹关键是把“实时告警用高精度数据”和“趋势分析用低精度数据”分开不然再大的磁盘也撑不住时间推移。4. 常见问题与排查技巧实录4.1 监控数据缺口与莫名尖峰先从时间戳和规则查起监控数据出现缺口是最常见也最头大的问题。我排查的顺序是先看采集端还在不在再看网络通不通再看存储端有没有锁。如果 target 状态是 UP 但指标就是有缺口大部分情况是抓取超时或者采集端自己逻辑卡住。嵌入式板子如果掉电重启MQTT 重连机制没做好上报数据会在重启窗口内缺失这种时候要同时看板子的日志和网关日志而不是只看监控平台。莫名尖峰多半出在规则上。CPU 使用率用 irate 算当节点发生调度时容易画出瞬间 100% 的尖刺TCP 连接数如果按连接创建事件计数重新结算周期也会出现尖峰。解决办法是先看 PromQL 函数是不是符合语义再看采集端有没有给指标做累加。最好在 Grafana 里比对原始指标和告警规则用的派生指标确认尖峰是真实故障还是计算方式带来的假象。4.2 告警风暴收敛抑制、静默、路由与值班窗口这次发版后第一天夜里我就被告警风暴教训了一顿。一台 Windows 服务器重启Zabbix 报连接数异常Prometheus 报该节点 K8s 调度失败夜莺又把两个系统的告警聚合在一起群里几分钟内刷了几十条消息。告警风暴的根源是告警规则之间没有建立依赖关系一台机器挂了下游应用全部跟着告警。收敛方案分三步第一步在夜莺里配置告警路由按机器宿主分组同一台机器上的告警合并成一条消息第二步配置抑制规则如果存在“主机 Down”级别的告警就把关联的应用告警抑制掉第三步是建立维护窗口发布和重启操作前统一静默对应机器的告警避免每次维护都触发风暴。还有一个小技巧把告警发送的 webhook 做去重判断同样的告警 key 在 15 分钟内不重复推送到群里夜间值班能被少吵醒很多次。4.3 摄像头监控码率上限与夜晚不灵敏的调整监控链路里有一块视频类内容经常被忽略就是摄像头监控的码率和成像。码率上限不是越高越好要根据分辨率和压缩算法综合判断。H.264 编码下720P 大概 2~4Mbps1080P 大概 4~8Mbps换成 H.265 后码率能降一半左右。如果画面变化快比如车间门口有频繁走动码率可以适度上调如果画面静止低位码率反而省存储。需要计算录像存储容量时会用到公式单路每小时存储量约等于 码率/8 × 3600 秒比如 4Mbps 码率一天大约 43GB30 天就是 1.3TB。这样可以反推存储服务器需要多大磁盘。海康威视摄像头夜晚不灵敏大多数不是设备坏了而是红外切换和曝光参数的锅。可以先把红外灯模式改成自动再把“日夜切换”策略从“自动”改成“定时切换”并校准时间最后适当调高 AGC 增益和开启 3D 降噪。如果还暗检查一下镜头前有没有异物遮挡。4.4 边缘部署监控误检率高模型、阈值与后处理两手抓边缘部署的 AI 监控经常遇到误检率偏高的问题尤其是 YOLO 这类目标检测模型部署到低算力设备后。误检率高的原因主要有三块一是模型量化后精度下降FP32 转 INT8 会丢一些难以察觉的细节二是部署场景的光照和训练集差异大三是阈值定得太低模型把大量背景目标当成检测对象。我这次的做法是先降低模型输入分辨率带来的误检影响。分辨率不变推理帧率可以保持稳定然后把置信度阈值从默认 0.25 调到 0.45误检有明显下降但同时可能漏检。所以同时加了帧间过滤连续两帧都检测到同一目标才算有效结果。ROI 区域屏蔽也很管用把监控画面里不可能出现目标的区域直接忽略掉排除大量背景误检。如果目标区域在夜间弱光环境可以考虑调整图像增强预处理而不是盲目改阈值。结尾处我再分享一点个人体会。监控系统每多一层故障排查的复杂度不是加一而是乘二所以链路设计时不要一味追求“什么都接”。像这次四个项目同日发版虽然协调和验证很累但链路打通之后新环境接入时基本只需要改采集配置和标签后续的告警和展示都能自动复用。如果你也在搭监控建议先不要急着上各种花哨面板先把五层链路里每一层的边界画清楚数据先跑通告警再看准体验会稳很多。
返回列表