4. 工单状态机:新建→处理中→挂起→已解决→关闭

状态机这东西,说白了就是给工单画了一条「生命线」。

我记得刚接手运维平台时,工单状态全靠人脑记忆。今天处理到哪了?不知道。明天谁来跟进?不清楚。直到有一次,一个核心告警因为「挂起」后没人管,硬生生拖成了事故——从那以后,我特别看重状态机的严谨性。

这一章,我们就来拆解这 5 个状态的流转规则。

4.1 核心五状态定义

每个状态都对应一个明确的处理阶段,不允许随意跳跃。你想想看,如果工单能从「新建」直接跳到「已解决」,中间的排查、变更、验证就全丢了。

状态 图标 含义 流转出口
新建 🆕 告警触发,工单生成,无人认领 → 处理中 / × 废弃
处理中 🔧 已被运维人员接手,正在排查/处置 → 已解决 / → 挂起
挂起 ⏸️ 因依赖第三方、等待资源等原因临时暂停 → 处理中(恢复)
已解决 ✅ 根因已定位,措施已执行,待确认 → 关闭 / ← 处理中(重新打开)
关闭 🔒 问题确认消除,工单归档,不再流转 终态(不可逆)
核心提示:「关闭」是永久终态。一旦关闭,就算告警再次出现,也必须走新建流程。我见过有些团队把「关闭」当垃圾桶,随手关随手开,最后审计时全乱了。

4.2 状态转移规则(必须遵守)

工单的状态不能随便跳。比如从「新建」直接到「已解决」,这在逻辑上说不通——你没处理,怎么就能解决呢?

允许的转移路径(正向):

  1. 新建 → 处理中(必须有人点击「认领」或系统自动分配)
  2. 处理中 → 已解决(必须填写处理措施和验证结果)
  3. 处理中 → 挂起(必须填写挂起原因、预计恢复时间)
  4. 挂起 → 处理中(系统自动恢复或人工点击「恢复处理」)
  5. 已解决 → 关闭(确认无误后归档)

允许的转移路径(逆向):

  1. 已解决 → 处理中(验证不通过,重新打开)
  2. 处理中 → 新建(极少用,仅限工单分配错误时「退回」)
⚠️ 严禁操作:「挂起 → 已解决」「新建 → 关闭」「挂起 → 关闭」。我曾经在一个项目中看到有人为了图省事,直接挂起后点关闭——结果那个问题三个月后又爆了,还因为没留记录,根本查不到原因。

4.3 挂起状态的特殊性

「挂起」是状态机里最容易出问题的一环。为什么?因为它会「冻结」工单的响应时间。

我跟你讲,很多团队的 SLA 计算就是被挂起搞崩的。

  • 挂起期间不计入处理时长:工单进入挂起后,SLA 时钟暂停。恢复处理时,时钟接着走。
  • 必须设置「最大挂起时长」:我个人习惯设为 24 小时。超过 24 小时未恢复,自动触发升级通知给值班经理。
  • 挂起理由不能敷衍:必须写明「等待某厂商补丁」「等待硬件到货」这类具体原因。我曾经见过有人写「等一会再说」——这就等于没有。
# 伪代码:挂起逻辑示例
def suspend_ticket(ticket_id, reason, expected_resume_at):
    if ticket.state != 'in_progress':
        raise InvalidTransitionError('只能在处理中状态挂起')
    
    ticket.state = 'suspended'
    ticket.suspend_reason = reason
    ticket.sla_pause_time = datetime.now()
    ticket.sla_resume_time = expected_resume_at
    
    # 注册定时任务,超时未恢复则升级
    register_timeout_job(
        at = expected_resume_at,
        action = lambda: escalate_ticket(ticket_id, '挂起超时')
    )

4.4 状态机流程图

把上面的规则画成图,会更直观一些。下面这张 SVG 图展示了完整的 5 个状态和它们之间的转移路径。

告警工单状态机流转图 工单状态机流转图 新建 处理中 挂起 已解决 关闭 废弃 认领/分配 措施完成 挂起原因 恢复处理 确认归档 验证不通过 无效告警 说明: 实线箭头 = 正向流转,虚线箭头 = 逆向退回(仅已解决可回退到处理中)。 挂起行为特殊:进入挂起时 SLA 暂停,恢复后继续计时。

4.5 常见「踩坑」记录

做状态机这么多年,有几个坑我印象特别深,拿出来给你提个醒。

  • 「挂起」变「僵尸工单」:挂起后没有自动提醒,结果一挂就是好几周,最后发现时第三方早处理完了。解决方案:强制设置最长挂起时间,超时自动升级。
  • 「已解决」直接跳「关闭」:缺少人工确认环节。我建议在「已解决」和「关闭」之间加一个「自动巡检」或「人工复核」的钩子,确保问题真的没了再关。
  • 状态没有日志:每次状态变更必须记录操作人、时间、原因。我曾经被审计追着问「这个工单为什么挂起又恢复?」——没有日志,根本说不清。
最佳实践:状态机的代码实现一定要用「状态模式」或「有限状态机库」。别手写 if-else,会把人写疯的。我个人偏好用 transitions 这个 Python 库,声明式配置,清晰又可控。

4.6 状态机与 SLA 的联动

状态机不是孤立的。它直接决定了 SLA 的计算逻辑。

状态 SLA 是否计时 备注
新建 ✅ 计时 从生成开始算响应时间
处理中 ✅ 计时 处理时长
挂起 ⏸️ 暂停 暂停时长不计入 SLA
已解决 ❌ 停止 等待确认,不超时
关闭 ❌ 停止 终态

记住一条原则:SLA 只对「未解决」的状态负责。挂起虽然不计时,但如果不加限制,就等于变相延长了 SLA。

我个人在设计状态机时,会在每个状态变更点埋一个「SLA 检查」钩子。比如:

  • 进入「处理中」时,检查是否超响应时间;
  • 挂起恢复时,检查剩余处理时间是否足够;
  • 已解决转关闭时,检查是否超过了「待确认」的最长时限(我通常设 4 小时,超时自动关闭)。

嗯,这块内容比较多,写到这里已经快 2000 字了。状态机是告警工单的骨架,骨架正了,后面的联动和闭环才不会歪。你回去可以结合自己系统的状态设计,看看有没有遗漏的路径或漏洞。