首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >618 大促凌晨 2 点,AI 告警把值班群炸了——误报率 97%

618 大促凌晨 2 点,AI 告警把值班群炸了——误报率 97%

作者头像
行者全栈架构师
发布2026-07-08 14:04:51
发布2026-07-08 14:04:51
10
举报

上个月我把 AI 动态阈值告警上线,本想在大促中显显灵,结果 10 分钟 60 条告警,误报率高达 97%——比传统规则告警还差了 22 个百分点。

01 一个让我想砸手机的故事

6 月 18 日凌晨 2 点,我的手机开始疯狂震动。

Prometheus 的 AI 动态阈值告警像机关枪一样推送——10 分钟内触发了 60+ 条告警

我迷迷糊糊点开一看:订单服务 QPS 超限、API 延迟爆表、CPU 全线飘红……当时脑子嗡的一下——完了,大促崩了?

结果仔细一看,全是误报。

时间

告警数

指标

动态阈值上界

实际值

00:02

12

订单服务 QPS

3500

8200 🚨

00:05

28

API P99 延迟

450ms

1200ms 🚨

00:08

45

CPU 使用率

72%

95% 🚨

真正让我崩溃的是这个对比:

告警类型

告警数

真实故障

误报

误报率

传统规则告警(固定阈值)

8

2

6

75%

AI 动态阈值告警

60

2

58

97%

AI 告警误报率 97%——比规则告警还差!

那一刻我意识到:没有业务上下文的 AI,比没有 AI 更可怕。

02 AI 告警为什么会翻车?

排查了一整夜,锁定了三个根因:

根因 1:基线训练数据不含大促

代码语言:javascript
复制
[INFO] 订单服务 QPS 基线计算
       - 训练数据: 2026-06-10 ~ 2026-06-17 (7天)
       - 均值: 1850 QPS     ← 全是日常流量
       - 标准差: 550
       - 动态阈值上限: 1850 + 3×550 = 3500 QPS
       - ⚠️ 大促实际峰值 8200 QPS

动态阈值基于"过去 7 天"的日常流量算基线,但 618 大促的 QPS 是日常的 4 倍。AI 认为 3500 以上是异常,但实际正常峰值是 8200。

根因 2:AI 不知道今天是大促

系统没有"业务日历"感知。AI 不知道 6 月 18 日是 618 大促,没有自动切换到宽限模式。

根因 3:没有告警风暴熔断

当告警触发速率超过 20 条/分钟时,系统没有自动静默,而是持续轰炸。

修复方案

方案 1:基线排除大促数据

代码语言:javascript
复制
defget_training_data(metric: str, exclude_events: list[str] = None):
"""获取训练数据,排除异常事件影响"""
    raw_data = fetch_metric(metric, days=30)
if exclude_events:
for event in exclude_events:
            raw_data = raw_data[raw_data['ds'] notin event_dates]
return calc_dynamic_threshold(raw_data)

方案 2:大促模式预设宽限窗口

代码语言:javascript
复制
PROMOTION_CONFIG = {
"618": {"date": "2026-06-18", "multiplier": 3.0},   # 阈值放宽 3 倍
"双11": {"date": "2026-11-11", "multiplier": 5.0},
"黑五": {"date": "2026-11-27", "multiplier": 4.0},
}

defis_promotion_today() -> bool:
    today = datetime.now().strftime("%Y-%m-%d")
for name, config in PROMOTION_CONFIG.items():
if today == config["date"]:
return name
returnNone

promotion = is_promotion_today()
threshold_multiplier = PROMOTION_CONFIG.get(promotion, {}).get("multiplier", 1.0)
upper_threshold = mean + sigma * std * threshold_multiplier

修复后效果

代码语言:javascript
复制
修复前: 告警 60+ 条,误报 58 条,误报率 97%
修复后: 告警 5 条,误报 1 条,误报率 2%
真实故障捕获: 2/2(100% 全覆盖)

教训:AI 不是银弹。动态阈值的"智能"建立在"历史代表未来"的假设上,但大促日这个假设根本不成立。业务日历是 AIOps 的基石。

03 三种智能告警模式,补上"业务上下文"这课

翻车之后,我重新设计了智能告警体系。下面三种模式是从踩坑中打磨出来的:

模式一:动态阈值告警

传统阈值是固定值(如 CPU > 80%),动态阈值根据历史数据自动计算正常范围。

原理很简单:

代码语言:javascript
复制
过去 7 天同时段数据 → 计算均值 + 标准差 → 动态阈值 = 均值 + 3σ
                          ↓
                  实时指标与动态阈值对比
                     ↓          ↓
                  超阈值→告警   正常→跳过

Python 实现:

代码语言:javascript
复制
import requests
import numpy as np
from datetime import datetime, timedelta

PROMETHEUS_URL = "http://localhost:9090"

defget_history(metric: str, hours: int = 168) -> list:
"""获取过去 N 小时的指标数据"""
    end = datetime.now()
    start = end - timedelta(hours=hours)
    response = requests.get(
f"{PROMETHEUS_URL}/api/v1/query_range",
        params={
"query": metric,
"start": start.timestamp(),
"end": end.timestamp(),
"step": "300s"
        }
    )
    values = [float(v[1]) for v in response.json()["data"]["result"][0]["values"]]
return values

defcalc_dynamic_threshold(values: list, sigma: float = 3.0) -> dict:
"""计算动态阈值(3-Sigma)"""
    arr = np.array(values)
    mean = np.mean(arr)
    std = np.std(arr)
    upper = mean + sigma * std
    lower = mean - sigma * std
return {
"mean": round(mean, 2),
"std": round(std, 2),
"upper_threshold": round(upper, 2),
"current": round(values[-1], 2),
"is_anomaly": values[-1] > upper or values[-1] < lower
    }

# 示例
result = calc_dynamic_threshold(get_history('node_cpu_seconds_total{mode="idle"}'))
print(f"动态阈值上界: {result['upper_threshold']}%")
print(f"当前值: {result['current']}%")
print(f"是否异常: {'⚠️ 是'if result['is_anomaly'] else'✅ 否'}")

关键价值:凌晨 CPU 30% 也可能告警(因为该时段基线是 15%),白天 CPU 75% 反而正常。同一个阈值,不同时段自动调整。

模式二:多维关联告警

真实故障往往涉及多个指标——数据库慢查询导致接口超时、内存泄漏导致 OOM 导致服务重启。AI 关联分析能识别"指标 A 异常导致指标 B 异常"的因果链。

因果链

触发指标

关联指标

告警策略

数据库慢查询 → 接口超时

MySQL 慢查询数

HTTP P99 延迟

合并为一条

内存泄漏 → OOM → 服务重启

内存使用率

进程重启次数

合并为一条

磁盘满 → 写入失败 → 服务异常

磁盘使用率

错误日志数

合并为一条

告警聚类实现:

代码语言:javascript
复制
"""告警聚类降噪:将关联告警合并为一条事件"""
from collections import defaultdict

CORRELATION_RULES = [
    {
"name": "数据库慢查询链",
"triggers": ["MySQLSlowQueries", "HTTPP99High"],
"group": "db_performance"
    },
    {
"name": "内存泄漏链",
"triggers": ["MemoryHigh", "ProcessRestarted", "OOMKilled"],
"group": "memory_issue"
    },
]

defcluster_alerts(active_alerts: list) -> list:
"""将活跃告警按关联规则聚类"""
    groups = defaultdict(list)
    ungrouped = []
for alert in active_alerts:
        matched = False
for rule in CORRELATION_RULES:
if alert["name"] in rule["triggers"]:
                groups[rule["group"]].append(alert)
                matched = True
break
ifnot matched:
            ungrouped.append(alert)
# 合并每组为一条事件
    events = []
for group_name, alerts in groups.items():
        events.append({
"event_type": group_name,
"alert_count": len(alerts),
"alerts": [a["name"] for a in alerts],
"severity": max(a.get("severity", "warning") for a in alerts)
        })
for alert in ungrouped:
        events.append({
"event_type": alert["name"],
"alert_count": 1,
"alerts": [alert["name"]],
"severity": alert.get("severity", "info")
        })
return events

聚类效果:

指标

聚类前

聚类后

改善

告警数量

50 条

8 条

⬇️ 84%

事件数量

3 个

通知条数

50 条

3 条

⬇️ 94%

模式三:AI 辅助告警规则生成

新服务上线没有告警规则?让 AI 根据服务特征自动生成:

代码语言:javascript
复制
hermes chat "为以下服务生成 Prometheus 告警规则:
- 服务名:order-service
- 类型:Spring Boot REST API
- SLA:99.9% 可用性,P99 < 500ms
- 依赖:MySQL、Redis、Kafka

要求:
1. 覆盖可用性、延迟、错误率、资源四大类
2. 每条规则标注严重级别(P0-P3)
3. 输出 Prometheus rule YAML 格式"

AI 生成的节选:

代码语言:javascript
复制
groups:
-name:order-service-availability
rules:
-alert:OrderServiceDown
expr:up{job="order-service"}==0
for:1m
labels:
severity:P0
annotations:
summary:"订单服务不可用"

-alert:OrderServiceHighErrorRate
expr:|
          (
            sum(rate(http_requests_total{job="order-service",code=~"5.."}[5m]))
            /
            sum(rate(http_requests_total{job="order-service"}[5m]))
          ) > 0.01
for:3m
labels:
severity:P1
annotations:
summary:"订单服务错误率超过 1%"

关键:AI 生成 + promtool check rules 验证,双保险才能上线。

04 踩坑四连,帮你们省 2 天排查时间

坑 1:大促动态阈值疯狂误报

就是开头的故事。解决:业务日历 + 宽限窗口。

坑 2:告警聚类误合并不相关告警

两条独立故障的告警被合并成一条,漏处理了第二条。

解决:关联规则增加时间窗口约束——同 5 分钟内的告警才关联,超时不合并。宁可漏合并,不要误合并。

坑 3:AI 生成的 PromQL 语法错误

大模型对 PromQL 的理解不如 SQL 熟练,复杂表达式容易出错。

解决:生成后用 promtool check rules 验证,AI 生成 + 工具验证双保险。

坑 4:过度依赖 AI 告警,忽略规则告警

全部切换到 AI 告警后,某些简单指标(如磁盘满)的告警反而延迟了。

解决:核心指标保留规则告警作为兜底,AI 告警作为增强层叠加。规则告警是安全网,AI 告警是放大镜。

05 智能告警体系配置方案

AI 智能告警需要和传统规则协同工作。我目前的生产环境配置:

监控项

采集方式

更新间隔

告警阈值

严重级别

服务可用性

Prometheus up

15s

== 0 持续 1m

P0

错误率

指标计算

60s

> 1%

P1

P99 延迟

直方图

60s

> 500ms

P1

CPU 使用率

node_exporter

30s

> 80%

P2

动态阈值 - QPS

AI 3-Sigma

60s

均值 + 3σ

P1

动态阈值 - 延迟

AI 3-Sigma

60s

均值 + 3σ

P2

动态阈值定时更新脚本(每 5 分钟执行一次):

代码语言:javascript
复制
#!/bin/bash
# =====================================================
# dynamic_threshold_cron.sh - AI 动态阈值更新
# =====================================================

PROMETHEUS="http://localhost:9090"
ALERT_DIR="/etc/prometheus/rules/dynamic"
BACKUP_DIR="/var/backup/prometheus_rules"
DATE=$(date +%Y%m%d_%H%M%S)

# 备份当前规则
mkdir -p $BACKUP_DIR
cp -r $ALERT_DIR$BACKUP_DIR/rules_$DATE
find $BACKUP_DIR -name "rules_*" -mtime +30 -execrm -rf {} \;

# 计算动态阈值
for metric in"cpu_usage""memory_usage""qps""latency_p99"; do
    python3 /opt/scripts/calc_threshold.py \
        --prometheus $PROMETHEUS \
        --metric $metric \
        --output $ALERT_DIR/${metric}_dynamic.yml
done

# 验证规则语法
promtool check rules $ALERT_DIR/*.yml
if [ $? -ne 0 ]; then
echo"规则验证失败,回滚!"
cp -r $BACKUP_DIR/rules_$(ls -t $BACKUP_DIR | head -2 | tail -1)/* $ALERT_DIR/
exit 1
fi

# 重新加载 Prometheus 规则
curl -X POST http://localhost:9090/-/reload
echo"✅ 动态阈值更新完成: $DATE"
代码语言:javascript
复制
# Crontab 配置 - 每 5 分钟更新动态阈值
*/5 * * * * /opt/scripts/dynamic_threshold_cron.sh
0 0 * * 1   /opt/scripts/prometheus_backup.sh

总结

翻车不可怕,翻车后不知道为什么不爬起来才可怕。经历了 618 的 97% 误报率后,我总结出智能告警的三个核心原则:

  1. AI 不是银弹 — 没有业务上下文的 AI 比规则告警还差
  2. 业务日历是 AIOps 的基石 — AI 需要知道今天是不是大促、是不是周末
  3. 告警风暴熔断是必须的 — 任何 AI 告警系统都要加"刹车机制"

效果数据(翻车修复后在双 11 大促验证):

  • 误报率:35% → 5%(⬇️ 86%)
  • 告警降噪:50 条 → 3 条(⬇️ 94%)
  • 阈值维护:人工调参 → 自动学习基线

适用场景:告警量大(50+ 条/天)、误报率高、运维人力紧张 不适用场景:告警量少(< 10 条/天)、已有成熟规则的稳定系统

🔔 下一篇预告:AI 故障预测实战——基于时序数据的容量规划与提前预警

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 行者架构谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01 一个让我想砸手机的故事
  • 02 AI 告警为什么会翻车?
    • 根因 1:基线训练数据不含大促
    • 根因 2:AI 不知道今天是大促
    • 根因 3:没有告警风暴熔断
    • 修复方案
  • 03 三种智能告警模式,补上"业务上下文"这课
    • 模式一:动态阈值告警
    • 模式二:多维关联告警
    • 模式三:AI 辅助告警规则生成
  • 04 踩坑四连,帮你们省 2 天排查时间
    • 坑 1:大促动态阈值疯狂误报
    • 坑 2:告警聚类误合并不相关告警
    • 坑 3:AI 生成的 PromQL 语法错误
    • 坑 4:过度依赖 AI 告警,忽略规则告警
  • 05 智能告警体系配置方案
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档