去年我们上了AIOps平台,厂商演示时各种漂亮的数据:告警压缩率90%、根因定位准确率85%、容量预测误差小于5%。当时我心想,这玩意儿真能这么神?
用了8个月,我必须说一句:AI在运维上确实有用,但翻车的次数也不少。我总结了5次印象比较深的判断错误,每次都给我上了不同的课。这些案例不是黑AI,而是想说明——如果你把AI的判断当圣旨,迟早要出事。
案例1:正常流量突增被判为攻击,自动限流坑了业务
### 现象
今年1月某个周二上午10:17,我们的订单服务QPS从平时2000突然飙到8500,持续了大概4分钟。AIOps平台的异常检测模块触发了告警,判定为"疑似DDoS攻击",然后自动执行了限流策略——把QPS上限设到了3000。
10:21,客服开始接到电话,用户反馈下单失败。业务侧直接炸了,因为那天正好是一个促销活动的预热期,流量突增是正常的。
### AI怎么判断的
平台用的是基于历史7天同时段数据的时序异常检测。平时这个时段QPS在1800-2200之间波动,8500已经超出3-sigma阈值,AI判定为异常流量。然后关联了WAF的规则引擎,因为没有匹配到已知爬虫特征,进一步判定为"未知攻击"。
### 实际根因
营销部门临时加了一个限时秒杀活动,提前在APP上推送了push通知。10:17是推送时间,用户集中涌入。这个活动没有提前通知技术团队,也没有在容量规划里预登记。
### 为什么AI会错
第一,AI的训练数据里没有"合法业务突增"这个模式。它见过的所有QPS飙升都是异常情况,要么是爬虫、要么是压测、要么是故障导致的重试风暴。一个合理的流量突增,对AI来说和攻击长得一模一样。
第二,AI缺少业务上下文。它不知道10:17有什么营销活动,因为这些信息根本没进到运维系统里。
### 后来怎么改的
三件事:
一,自动限流策略从"立即执行"改成"延迟60秒执行+通知确认"。AI可以自动触发限流,但给运维60秒窗口来人工overide。
二,跟营销团队建了个流程,所有营销活动提前24小时在容量系统里登记,系统会在活动时间段标记为"预期流量突增"。
三,在AI的判定逻辑里加了规则:如果QPS突增的同时,转化率和支付成功率也在同步上涨(说明是真实用户在买东西),不触发限流。攻击流量通常转化率极低。
### 教训
AI只看技术指标,不看业务上下文。任何自动化决策在触发前,必须留人工确认窗口。尤其是限流、降级这种直接影响业务的操作。
案例2:磁盘IO高被判为磁盘故障,实际是数据库大批量UPDATE
### 现象
今年3月,监控大盘显示某台MySQL从库服务器的磁盘IO util持续100%,iops从平时的800飙到12000。AIOps平台分析后告警:"磁盘亚健康,预计4小时内故障,建议立即更换。"
值班同事看到这个告警直接慌了,准备走换盘流程。我拦住了他,因为我看了一眼慢查询日志。
### AI怎么判断的
AI采集了磁盘的iops、吞吐量、IO util、IO等待时间、磁盘队列长度这几个指标。IO util持续100%+队列深度大于8+IO等待时间大于50ms,这些特征跟平台训练数据里的"磁盘故障前兆"模式匹配度0.87,所以判定为磁盘亚健康。
### 实际根因
业务侧在跑一个数据清洗任务,对一张2000万行的表做了批量UPDATE:
UPDATE user_behavior_log SET status = 'archived' WHERE create_time < '2025-01-01' AND status = 'active';这条SQL没分批,一口气跑了40分钟,产生大量redo log写入和随机IO,把磁盘IO打满了。磁盘本身没有任何问题。
### 为什么AI会错
AI只看了磁盘层面的指标,没有关联数据库的慢查询日志。从磁盘指标的角度看,IO util 100%、队列深度高、IO等待高,确实跟磁盘故障的特征很像。但这些指标也是"有进程在疯狂写磁盘"的表现,AI区分不了这两种情况。
另外,AI的判定逻辑里缺了一个维度:如果同时看MySQL的`threads_running`和`slow_queries`指标,就能发现异常。当时threads_running从平时的5飙到了42,slow_queries每秒新增15条,但这些信号没有被关联到磁盘IO的分析里。
### 后来怎么改的
一,在磁盘IO异常的判定规则里加了关联条件:如果同时段MySQL slow_queries数量也在飙升,优先判定为"数据库IO压力",而不是磁盘故障。
二,告警分级从单一的"磁盘故障"改为多维度:磁盘指标异常 → 关联数据库指标 → 关联进程级IO → 综合判定。
三,跟DBA约定,大批量UPDATE必须分批执行,单批次不超过1万行,中间加sleep:
-- 分批执行,每批5000行 UPDATE user_behavior_log SET status = 'archived' WHERE id BETWEEN 1 AND 5000 AND status = 'active'; -- 应用层循环,每批之间sleep 200ms### 教训
单维度指标异常不代表硬件故障。AI的根因分析必须跨维度关联,光看磁盘指标是不够的。这也是为什么AIOps平台需要接入尽可能多的数据源——不是为了数据量好看,而是为了让AI有更多上下文做判断。
案例3:告警聚类把两个不相关故障合并了,漏了真故障
### 现象
这是最严重的一次。4月某天凌晨2:30,系统同时出了两个问题:一个是Redis集群一个节点OOM重启,另一个是Kafka的某个partition消费延迟。两个问题发生在同一时间,影响的服务有部分重叠。
AIOps的告警聚类功能把这两组告警合并成一条:"Redis集群异常导致消息消费延迟"。值班同事按这个方向排查,花了一个小时查Redis,结果Kafka那边延迟越来越严重,最终导致下游订单处理超时,影响了一批凌晨的订单。
### AI怎么判断的
告警聚类的逻辑是基于时间窗口(5分钟内)和拓扑关联(两个告警的源服务在CMDB里有依赖关系)。Redis和Kafka都在订单服务的依赖链上,告警时间几乎同步,AI按相似度把它们聚成了一组,然后选了"先发生"的Redis告警作为根因。
### 实际根因
两个故障是完全独立的。Redis节点OOM是因为一个同事部署了一个新版本,连接池配置写错,一个连接泄漏导致内存涨到上限。Kafka消费延迟是因为上游一个数据同步任务在凌晨跑批,一次性推了200万条消息到Kafka,消费端处理不过来。
这两个问题时间上撞一起了纯属巧合,没有任何因果关系。
### 为什么AI会错
第一,告警聚类默认"时间相近+拓扑关联"就是因果关系,这个假设本身就有问题。两个不相关的故障完全可能同时发生,尤其是在凌晨跑批任务密集的时段。
第二,AI选根因的逻辑是"先发生的那个",但实际上Redis的OOM告警比Kafka延迟告警早了40秒,这40秒并不能说明因果关系。
第三,聚类后把多条告警折叠成一条,值班同事看到的只是摘要,不会去翻每条原始告警。真正的Kafka延迟告警被"吸收"了,没有单独通知。
### 后来怎么改的
一,告警聚类只做展示层面的聚合,不做通知层面的折叠。每个原始告警仍然独立通知,聚类只是方便值班同事在大盘上看整体情况。
二,聚类后增加一个"关联性确认"步骤:AI给出聚类结论的同时,列出每条原始告警,让值班同事自己判断是否真的有关联。
三,在告警通知里加了一个提示:如果聚类内有告警在30分钟内没有恢复,自动拆分为独立告警重新通知。防止一个故障被另一个故障"淹没"。
### 教训
告警聚类最大的风险是"假阳性关联"——把碰巧同时发生的事当成因果。聚类可以帮你减少告警噪音,但绝对不能把原始信息丢掉。值班同事需要能看到每一条原始告警,自己判断关联性,而不是只看AI给的"摘要结论"。
案例4:根因分析给出错误建议:建议重启,实际是配置错误
### 现象
5月某个周六,我们一个支付网关服务开始报错,错误率从0.1%升到5%。AIOps的根因分析模块给出建议:"实例实例异常,建议重启服务实例。"
值班同事按照建议执行了重启。重启后错误率短暂下降到1%,5分钟后又涨回5%。反复重启了3次,问题没解决。
### AI怎么判断的
AI分析了以下信号:CPU使用率正常、内存正常、网络延迟正常、磁盘IO正常。然后看了下JVM的GC日志,发现Full GC次数从每小时2次增加到每小时8次。AI判定为"JVM内存异常导致服务不稳定",建议重启释放内存。
### 实际根因
根本不是内存问题。那天有个同事周五下班前改了一个配置,把超时时间从3秒改成了30秒:
# 改之前 payment: upstream-timeout: 3000 # 3秒 # 改之后(手滑多打了个0) payment: upstream-timeout: 30000 # 30秒上游支付通道正常响应在500ms以内,超时设成30秒后,遇到上游偶发慢响应时请求不会快速超时重试,而是堆积在连接池里等待。连接池被打满后,新请求直接报错。Full GC次数增加是因为堆积的请求对象在堆里驻留时间变长了——这是症状不是原因。
### 为什么AI会错
第一,AI看到了GC异常(症状),但没看到配置变更(根因)。因为配置变更是通过Git提交的,AI没有关联到代码仓库的变更记录。
第二,重启后错误率短暂下降,这个现象反而误导了AI,让它认为"重启方向是对的,只是没彻底解决"。实际上重启只是清空了堆积的连接池,过几分钟又满了。
第三,AI的根因建议里缺少"配置变更检查"这一步。它只会从运行时指标里找原因,不会回头看"最近有什么变更"。
### 后来怎么改的
一,根因分析流程里增加变更关联检查:每次故障分析先查最近24小时的变更记录(代码部署、配置修改、扩缩容),如果有变更,优先排查变更。
# 根因分析逻辑变更 def analyze_root_cause(alert): # 第一步:查最近变更 recent_changes = get_recent_changes(hours=24) if recent_changes: changes_analysis = analyze_changes(alert, recent_changes) if changes_analysis.has_correlation: return changes_analysis # 第二步:指标分析(原来的逻辑) return metric_based_analysis(alert)二,配置变更上线前增加校验:超时时间超过10秒的需要额外审批,防止误改。
三,AI的根因建议里增加"变更时间线"展示,让值班同事能看到"故障前30分钟有什么变更",自己关联判断。
### 教训
80%的故障是变更引起的(这个数字是我们统计的,半年内47次故障里38次跟变更有关)。如果AI的根因分析不看变更记录,只看运行时指标,基本等于隔靴搔痒。根因分析的第一步应该是"最近改了什么",而不是"指标哪里不对"。
案例5:容量预测偏差大,过度扩容浪费成本
### 现象
6月初,AIOps的容量预测模块建议我们把订单服务的集群从12台扩到22台,理由是"预测7月日均QPS将达到12000,当前容量不足以应对"。我们按建议扩了,结果7月实际日均QPS峰值是6800,12台完全扛得住。多出来的10台机器白白跑了20天,云成本多花了大概4万块。
### AI怎么判断的
容量预测用的是Prophet时序预测模型,输入过去90天的QPS数据。模型看到5-6月QPS有上升趋势(从日均3000涨到5500),外推到7月预测12000。
### 实际根因
5-6月QPS上升有两个原因:一是自然增长(月增长率8%),二是6月有个限时活动带了临时流量。AI把活动带来的临时流量也算进了趋势,线性外推到7月。但活动6月底就结束了,7月QPS会回落到自然增长曲线。
另外,模型没有考虑季节性因素。7月是暑假,部分B端客户的使用量会下降,这个季节性模式在历史数据里其实有体现,但Prophet没捕捉到,因为训练数据只有90天,不够提取年度季节性。
### 为什么AI会错
第一,训练数据太短。90天的数据能提取周季节性,但年度季节性需要至少一年的数据。我们接入AIOps才8个月,历史数据不够。
第二,模型没有区分"趋势增长"和"临时事件"。活动带来的流量突增是临时事件,不应该被当作趋势外推。
第三,预测结果没有置信区间。AI给了个12000的点预测值,但没有告诉用户"这个预测的误差范围是±40%",导致我们按上限做了扩容决策。
### 后来怎么改的
一,容量预测改成区间预测+多场景:
# 预测结果不只给一个值 def capacity_forecast(history): base_trend = extract_natural_growth(history) # 自然增长趋势 seasonal = extract_seasonal_pattern(history) # 季节性因子 # 三种场景 optimistic = base_trend * (1 + seasonal) * 0.8 expected = base_trend * (1 + seasonal) pessimistic = base_trend * (1 + seasonal) * 1.2 return { 'optimistic': optimistic, 'expected': expected, 'pessimistic': pessimistic, 'confidence': 'medium', # 数据不足时降低置信度 'note': '训练数据不足365天,年度季节性未纳入' }二,扩容建议改成"分阶段扩容":先扩到16台观察一周,根据实际流量再决定是否继续扩。避免一步到位的过度扩容。
三,积累更长的历史数据。现在我们把所有指标数据都归档到S3,等数据积累到一年以上再做年度季节性分析。
### 教训
AI的预测值不是真理,尤其数据量不够的时候。看容量预测建议时,一定要问三个问题:训练数据够不够长?预测的趋势里有没有临时事件被当成了长期趋势?有没有给置信区间?如果这三个问题没有明确答案,建议保守决策,分阶段扩容。
总结:AI是辅助不是替代
这5次翻车经历让我对AIOps的态度变得比较务实。AI在以下场景确实能帮上忙:
告警降噪:把同源告警合并展示,减少值班同事的视觉负担 指标异常检测:发现人工没注意到的指标波动趋势 容量规划参考:作为决策的参考输入之一
但在以下场景,AI的判断必须人工复核:
任何会触发自动化操作(限流、降级、重启、扩缩容)的判断 根因分析的建议(尤其涉及变更关联时) 容量预测(尤其训练数据不足时)
我总结了几条原则:
第一,AI的判断必须留人工确认窗口。 自动化执行可以有,但必须给运维人员60-120秒的窗口来overide。完全自动的闭环目前还不现实。
第二,根因分析第一看变更。 80%的故障跟变更有关。如果AI不看变更记录,它给的根因建议基本可以忽略。
第三,预测结果要带置信度。 没有置信区间的预测值等于没有参考价值。做容量决策时,按预测值的60-80%来规划,留安全余量。
第四,聚类不等于因果。 同时发生的事件不一定有因果关系。告警聚类可以做展示优化,但不要把原始信息丢掉。
第五,必须有fallback。 如果AIOps平台自己挂了,你必须有一套纯人工的流程兜底。我们的运维手册里每个AI自动化操作旁边都标注了人工操作步骤。
上AI不是目的,减少故障、降低成本才是。如果AI反而增加了误操作和资源浪费,那不如不上。
---
你们在用AIOps的过程中遇到过哪些翻车的情况? 欢迎在评论区分享你的案例。我觉得这类"失败复盘"比成功案例有价值得多,别人的坑就是你的经验。如果觉得有用,转发给你的运维同事看看。
夜雨聆风