最近有朋友问,明明服务器负载都快拉满了,监控系统却一声不吭,告警死活不触发。这种情况其实挺常见的,尤其在运维压力大的时候,一个没注意,小问题就演变成线上事故。
时间不同步,告警直接失效
某次排查发现,一台主机的时钟比NTP服务器慢了将近15分钟。结果呢?监控平台收到的数据时间戳对不上,规则判定为“过期数据”,直接丢弃。告警自然不会触发。这种问题在虚拟机迁移或宿主机重启后特别容易出现,建议定期检查 ntpd 或 chrony 的同步状态。
阈值设置太激进
有人为了减少误报,把CPU使用率告警阈值设成95%以上持续10分钟。可现实是,服务崩溃往往发生在资源突增的几十秒内。等真达到阈值,服务早就挂了。更合理的做法是设置多级预警,比如75%提示、85%预警、90%紧急,配合短周期检测。
监控项配置错误
曾见过一个案例:Zabbix里配置的是监控http://localhost/status,但应用实际监听在127.0.0.1:8080,而localhost被解析到了IPv6地址,导致请求失败。表面上看采集不到数据,其实是网络协议没对上。这类问题用curl手动测试一下就能暴露:
curl -4 http://localhost/status
告警规则被意外屏蔽
有些平台支持维护窗口或静默策略。比如Prometheus Alertmanager可以配置inhibit_rules来抑制重复告警。但如果规则写得太宽泛,可能把本该触发的告警也压住了。检查配置文件中是否有类似这样的规则:
inhibit_rules:\n - source_match:\n severity: 'warning'\n target_match:\n severity: 'critical'\n equal: ['alertname', 'job']
这条规则会让critical级别的告警抑制同名的warning告警,但如果critical没触发,warning又被抑制了,那就全没了。
日志监控路径写错了
用ELK做日志告警时,有人把Filebeat的输入路径写成/var/log/app.log,但实际上应用生成的是带日期的滚动日志/var/log/app.log.2024-05-20。结果就是Filebeat读不到实时日志,整个链路断掉。应该改成通配符路径:
paths:\n - /var/log/app.log*\n - /var/log/app/*.log
网络隔离导致心跳丢失
在混合云环境下,本地IDC的监控Agent要上报到公有云的SaaS平台。如果防火墙只放行了HTTP出站,没允许Agent所需的特定端口(比如Zabbix默认的10050),数据传不出去,平台认为主机离线,反而把告警停了。这时候得查安全组和ACL规则,确保双向通信正常。
监控告警不触发,很多时候不是系统有问题,而是我们忽略了细节。与其等出事再救火,不如定期做一次告警有效性验证,比如故意制造一次高负载,看看能不能收到通知。这才是真正的防患于未然。