欢迎光临
我们一直在努力

AIOps 不是银弹:自动化之前先把流程标准化

AIOps 不是银弹:自动化之前先把流程标准化

一、自动化投入产出的典型反模式:自动化了一个混乱的流程

聊 AIOps 之前先看一个真实的场景。某团队有 5 个微服务,运维流程如下:每日 10 点在办公群里手动收集各服务负责人的上线需求 → 在 Excel 里排优先级 → 在 Jira 里建 ticket → 手动跑 Jenkins Job → SSH 到节点检查结果 → 如果失败在群里喊一声然后手动回滚 → 在 Excel 更新状态。这个流程耗时 90 分钟,团队决定引入 AIOps 做"智能变更编排"——自动排期、智能回滚、AI 推荐部署窗口。

结果是什么?AIOps 系统完美地自动化了一个混乱的流程。以前是人在 Excel 里乱排,现在是 AI 在平台里乱排——AI 推荐凌晨 3 点做部署,因为"历史数据显示这个时间点系统负载最低",但它不知道凌晨 3 点没有值班人员,出了问题根本没人处理。这就是自动化一个未经标准化的流程的典型代价:你获得的不是效率提升,而是更隐蔽的混乱。

AIOps 的价值层级是有顺序的:标准化 → 自动化 → 智能化。跳过标准化直接做智能化,就像在没有地基的沼泽上盖摩天楼。运维流程标准化的意思不是"大家用一种工具",而是"同一个操作在任何时间、任何人、任何情况下都应该有一致的输入和输出"。

二、标准化的三层模型:SOP → Tool → Platform

层级一:SOP(标准操作流程)。 SOP 不是文档。SOP 是经过验证的、可被新人独立复现的完整操作序列。一条合格的 SOP 应该包含:前置检查(执行前必须确认什么)、操作步骤(每一步的精确命令或操作)、验证点(如何判断这一步成功了)、回滚措施(如果出错了怎么退回到操作前的状态)、例外处理(超出预期的错误怎么升级)。

层级二:工具化。 SOP 确认有效后,把其中的核心步骤转化成脚本或 CLI 工具。这个阶段的关键是不求全——先实现 20% 的高频操作,覆盖 80% 的工作量。工具化的质量标准:输入输出结构化(JSON 格式,不依赖人眼解析)、错误分类(超时和权限不够是不同的错误类型,不是统一返回 exit 1)、幂等性(同一个操作执行两次不会产生副作用)。

层级三:平台化。 工具积累到 10 个以上后,把工具串联成工作流。平台化的核心是两个能力:编排——工具 A 的输出作为工具 B 的输入,中间有分支判断和条件等待;审计——谁在什么时间做了什么操作,操作前后的状态变化是什么。

层级四:智能化(AIOps)。 前三个层级都成熟之后,AI 才能发挥作用:推荐最优的变更窗口、预测变更风险、自动归类告警、推荐处理方案。AI 的价值不在于替代 SOP,而在于处理 SOP 覆盖不了的不确定性场景——比如"当前集群有 3 个非 Critical 的告警,是否还应该执行计划中的灰度发布?"

三、SOP 的工程化:从 Word 文档到可验证的执行流

// sop/runbook_executor.go
package sop

import (
"context"
"fmt"
"time"
)

// RunbookStep SOP 中的单个步骤
type RunbookStep struct {
Name string
Command string // 执行的实际命令
PreCheck func(context.Context) error // 前置检查:执行此步骤前必须通过
PostVerify func(context.Context) error // 后置验证:执行后必须通过
Rollback func(context.Context) error // 回滚函数:失败时执行的恢复操作
MaxRetries int
Timeout time.Duration
}

// Runbook SOP 的完整定义
type Runbook struct {
Name string
Version string
Description string
Steps []RunbookStep
// 运行条件:SOP 仅在此前提条件满足时才能开始
Prerequisites func(context.Context) error
}

// RunbookExecutor SOP 执行器
// 每次执行记录开始状态、每一步的结果、最终状态,形成完整的审计日志
type RunbookExecutor struct {
Log []StepLog
}

type StepLog struct {
StepName string
StartTime time.Time
EndTime time.Time
Success bool
Error string
RetryCount int
}

// Execute 严格按照 SOP 的顺序执行所有步骤
// 任何一步失败都会先执行回滚再终止——不会留下半完成的危险状态
func (e *RunbookExecutor) Execute(ctx context.Context, rb Runbook) error {
// 前置检查:运行环境是否满足 SOP 的前提条件
if rb.Prerequisites != nil {
if err := rb.Prerequisites(ctx); err != nil {
return fmt.Errorf("sop %s: prerequisites check failed: %w", rb.Name, err)
}
}

for stepIdx, step := range rb.Steps {
log := StepLog{
StepName: step.Name,
StartTime: time.Now(),
}

// 步骤内置的重试机制:瞬时性错误(网络闪断等)通过重试自愈
var lastErr error
for attempt := 0; attempt <= step.MaxRetries; attempt++ {
log.RetryCount = attempt

// 前置检查:每步执行前验证前置条件
if step.PreCheck != nil {
if err := step.PreCheck(ctx); err != nil {
lastErr = fmt.Errorf("pre-check: %w", err)
time.Sleep(5 * time.Second)
continue
}
}

// 执行带超时的实际命令
stepCtx, cancel := context.WithTimeout(ctx, step.Timeout)
err := e.executeCommand(stepCtx, step.Command)
cancel()

if err == nil {
// 后置验证:确保操作结果符合预期
if step.PostVerify != nil {
if verifyErr := step.PostVerify(ctx); verifyErr != nil {
lastErr = fmt.Errorf("post-verify: %w", verifyErr)
time.Sleep(5 * time.Second)
continue
}
}
// 步骤完全成功
log.Success = true
break
}

lastErr = err
if attempt < step.MaxRetries {
time.Sleep(time.Duration(attempt+1) * 10 * time.Second)
}
}

log.EndTime = time.Now()
if lastErr != nil {
log.Error = lastErr.Error()
}
e.Log = append(e.Log, log)

// 步骤失败的处理:先执行回滚,再终止整个 Runbook
if !log.Success {
if step.Rollback != nil {
rbCtx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
defer cancel()
if rbErr := step.Rollback(rbCtx); rbErr != nil {
return fmt.Errorf("sop %s: step %d '%s' failed and rollback also failed: %v (original error: %v)",
rb.Name, stepIdx, step.Name, rbErr, lastErr)
}
}
return fmt.Errorf("sop %s: step %d '%s' failed after %d retries: %v",
rb.Name, stepIdx, step.Name, step.MaxRetries, lastErr)
}
}

return nil
}

func (e *RunbookExecutor) executeCommand(ctx context.Context, command string) error {
// 实际命令执行逻辑
// 生产环境应通过安全的执行沙箱来运行命令
return nil
}

这个执行器的核心约束:每一步都有前置检查、后置验证和回滚函数。前置检查负责"这个步骤现在该不该做",后置验证负责"这个步骤做对了没有",回滚函数负责"如果没做对能不能退回去"。三者缺一,SOP 就不合格。

四、标准化投入的 ROI 计算:什么流程值得先标准化

不是所有流程都值得标准化——写一个完整的运维 Runbook 耗时 2 到 4 个小时,维护成本每年约 10 小时。判断一个流程是否值得标准化的计算方式:

ROI = (年度执行次数 × 单次平均耗时 × 标准化后的效率提升) / (标准化投入 + 年度维护成本)

假设一个发布流程:

  • 年度执行次数:200 次(平均每个工作日一次)
  • 单次平均耗时:90 分钟
  • 标准化后预计将时间压缩到 35 分钟(节省 61%)
  • 标准化文档编写:3 小时
  • 年度维护:10 小时
  • ROI = (200 × 90 × 0.61) / (3 + 10) = 10,980 / 13 ≈ 845 分钟回本率 → 投入 780 分钟,节省 10,980 分钟,净收益 10,200 分钟。

如果流程年度执行次数只有 12 次(每月一次),同样的计算得到 ROI = (12 × 90 × 0.61) / 13 ≈ 50 分钟回本率——投入 780 分钟节省 659 分钟,净亏损 121 分钟。标准化不值得。 所以判断标准只有一个:高频率流程先标准化,低频流程保持人工文档,一次性操作不用标准化。

五、总结

AIOps 落地的前提是运维流程标准化。顺序不能乱:

  • SOP 先行。 把高频操作写成可被新人独立复现的 Runbook,附带前置检查、验证点和回滚方案。
  • 工具化紧随。 把 SOP 中的核心步骤脚本化,但不追求全量自动化——先覆盖 80% 的路径。
  • 平台化配合。 工具积累到一定量后编排成工作流,加入审计和权限控制。
  • AI 最后上场。 在前三步稳定的基础上,AI 才能从"自动执行 SOP"进化到"在 SOP 的边缘场景提供决策建议"。
  • AIOps 不是靠算法就能解决的问题。自动化一个混乱的流程,得到的是更危险的混乱。基础设施不需要漂亮话——把标准化做到 80 分,自动化 60 分就能产生价值;标准化 20 分,自动化做成 100 分也是浪费。

    赞(0)
    未经允许不得转载:171主机测评 » AIOps 不是银弹:自动化之前先把流程标准化
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址