自动化系统告警分级:去重静默与风暴抑制实战

举报
yd_254065487 发表于 2026/11/08 05:24:06 2026/11/08
【摘要】 解决自动化巡检中日报被忽略、同类告警刷屏及夜间噪声干扰问题,给出基于状态去重与静默时段的告警分级落地代码。

日报推送在凌晨被忽略的故障现场

上周我们的自动化巡检脚本在凌晨 02:15 触发了一次磁盘使用率超 95% 的异常。由于系统设计了'每天推一条日报'的汇总机制,实时异常被合并到了早上 08:00 的日报里推送到企业微信。运维同学在通勤路上划过群消息,完全没注意那行小字。等线上服务因日志写满宕机时,dmesg 里已经刷满了 blk_update_request: I/O error, dev vda, sector 123456。这证明非紧急信息不能与紧急故障共用通道,出事才推的实时通道必须独立,否则故障现场会被安静的日报彻底掩盖。

timeSensitive 与 active 的字段取舍

在重构告警模块时,我们定义了告警结构体中的两个核心布尔字段:timeSensitive 与 active。timeSensitive 标识该告警是否时间敏感(如服务进程退出、核心接口 5xx),active 标识当前是否处于激活可推送状态(受维护窗口控制)。这两个字段的取舍直接决定告警路由。

取舍逻辑必须清晰:若 active=false,即便 timeSensitive=true 也不推(如版本发布窗口);若 timeSensitive=false(如容量趋势预测),即便 active=true 也仅进入日报池。我们在华为云 FunctionGraph 中实现的判断逻辑如下,通过不同的 SMN Topic 隔离实时与离线:

def route_alert(alert): if alert.timeSensitive and alert.active: publish_to_smn(alert, topic='urn:smn:cn-north-4:proj:urgent') elif alert.active: append_to_daily_digest(alert)

调用 SMN 发布接口时,若 Token 失效会收到 requests.exceptions.HTTPError: 401 Client Error,需提前刷新 AK/SK 换取的临时 Token,否则 urgent 通道会静默失败。

基于 state 的当日同类告警去重

同一天内如果 API 网关抖动,可能一小时内产生几十条'HTTP 5xx 升高'告警。我们利用华为云分布式缓存服务 DCS 的 Redis 维护一个 state 去重键:alert:{date}:{alert_type},确保同一天同类告警只推一次。

具体可复现步骤:

  • 告警触发时,对 Redis 执行 SET alert:2026-11-07:api_5xx 1 NX EX 86400
  • 若 Redis 返回 nil,说明当日已推过,直接丢弃或仅计数 +1
  • 若返回 OK,调用 SMN 推送并附带当日累计次数

对应的 Python 片段,部署在华为云 ECS 或 FunctionGraph 均可:

import redis r = redis.Redis(host='192.168.1.100', port=6379) key = f'alert:2026-11-07:api_5xx' if r.set(key, 1, nx=True, ex=86400): print('first time, send alert') else: print('duplicate, skip')

这保证了同一天同类告警只推一次,避免企业微信被同一条消息刷屏,也让值班同学信任每一条弹窗。

夜间静默时段的服务挂掉与库存告警

我们设定 23:00 至 07:00 为静默时段,绝大多数告警延后到早 8 点日报。但有两个例外必须穿透静默:服务进程退出(服务挂掉)与库存低于安全水位(库存告警)。在华为云 FunctionGraph 的定时器触发或 ECS 上的 cron 调度入口做小时判断:

from datetime import datetime hour = datetime.now().hour if 23 <= hour or hour < 7: if not (alert.type == 'service_down' or alert.type == 'inventory_low'): return # 静默丢弃,不调用 SMN

这样夜间只推服务挂掉与库存告警,其余如'证书即将过期'自然进入次日日报,值班同学不会被无效消息叫醒,同时核心链路挂掉能第一时间收到短信。

抑制告警风暴淹没真实故障

曾经一次上游 DNS 解析失败,导致 200 个微服务实例同时报'依赖不可用',真实根因被海量告警淹没。我们在聚合层使用 Redis ZSET 实现滑动窗口限流,确保关键错误不被噪声覆盖:

  • 统计 60 秒内同 root_cause 标签的告警数
  • 超过 50 条时,只发一条汇总告警,日志打印 Alert storm detected: 152 alerts in 60s, threshold 50
  • 其余同类转入静默计数,每 10 分钟汇报一次增量
import time, redis r = redis.Redis() now = time.time() r.zadd('storm:api_5xx', {str(now): now}) r.zremrangebyscore('storm:api_5xx', 0, now-60) if r.zcard('storm:api_5xx') > 50: send_storm_summary() # 抑制单条,推送汇总

这套分级逻辑上线后,误报率大幅下降,真实故障平均发现时间从 25 分钟缩到 3 分钟,且华为云 SMN 的调用成本也降低了一半,企业微信告警群恢复了该有的严肃性。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。