公司刚上线的订单服务突然变慢,运维群里跳出一条红色告警:‘数据库连接池耗尽’。大家第一反应是查数据库,结果 CPU、内存都正常。后来发现,真正的问题出在监控系统本身——部分节点没上报数据,导致负载统计失真。
监控不是摆设,得会看
很多团队部署了 Zabbix、Prometheus 或者阿里云监控,但只用来‘看图表’。一旦出问题,第一句话往往是‘监控有没有报警?’ 其实更该问的是:‘监控数据全不全?准不准?’
比如某次线上接口超时,监控显示服务器负载很低,看起来没问题。可实际上,那台机器的 Node Exporter 进程挂了,已经断报 20 分钟。监控界面还在用缓存数据插值显示,给人一种‘一切正常’的错觉。
常见监控盲区
监控系统本身也是系统,它会出问题。最常见的几类情况:
- 采集 agent 崩溃或未启动(如 collectd、telegraf)
- 网络策略拦截了监控端口(比如安全组没开 9100)
- 目标服务重启后没暴露 /metrics 接口
- 时间不同步导致指标对不上
有一次我们排查 Kafka 消费延迟,发现监控图上 Lag 一直是 0。后来登录机器手动 curl 才发现,/metrics 接口返回 500,而监控系统只是静静地‘收不到数据’,并没有主动告警。
加一层监控的监控
别笑,这很必要。最简单的办法是加一个‘存活检测’规则:
up == 0
Prometheus 里这个表达式能直接找出所有失联的目标。我们可以基于它设置告警:如果某个实例连续 2 分钟不可用,立即通知。
还可以写个脚本定期检查关键 metric 是否更新:
#!/bin/bash
LAST_UPDATE=$(curl -s http://your-prometheus/api/v1/query?query='time%7Bjob%3D%22node%22%7D' | jq '.data.result[0].value[1]')
DIFF=$(( $(date +%s) - $(echo $LAST_UPDATE | cut -d. -f1) ))
if [ $DIFF -gt 180 ]; then
echo "警告:节点监控数据已超过3分钟未更新"
fi
别只盯着数字,要还原链路
用户说‘页面打不开’,你看到 Web 服务器 CPU 飙高,就认定是服务扛不住?未必。可能是下游认证服务响应变慢,导致请求堆积。
这时候需要关联查看多个指标:API 延迟、调用链追踪、日志错误频率。用 Grafana 把它们拼在同一面板上,一眼就能看出先后顺序。
有次我们发现定时任务大面积失败,监控显示 Redis 响应时间暴涨。深入一看,其实是某台主机的磁盘 IO 太高,影响了 Redis 的持久化,进而拖慢整个实例。这种跨层问题,单看一个维度根本发现不了。
让监控说实话
最好的监控系统不是图表多好看,而是能在关键时刻告诉你‘哪里看不见了’。建议每个核心服务都加上以下三条规则:
- 数据上报心跳检测
- 关键指标变化率告警(比如 QPS 突降 80%)
- 与其他系统的时间差校验
监控系统不是万能药,但它能帮你少走弯路。问题是,当你以为它在工作的时候,它可能早就沉默了。