非官方社区教程 · 内容整理自公开资料 · 豆包工作为字节跳动产品,本站与官方无关
豆包工作教程
首页/ 可靠性工程/状态机设计与实现

状态机设计与实现

---

章节:进阶篇第5章
难度:⭐⭐⭐ 进阶级
阅读时间:25-30 分钟
核心收获:掌握状态机设计方法,学会用状态机建模自动化任务


8.1 理论要点:状态机的核心概念

8.1.1 什么是状态机

状态机(State Machine) 是一种建模方法,将系统的行为抽象为: - 状态(State):系统在某一时刻的处境 - 转移(Transition):从一个状态到另一个状态的变化 - 触发条件(Trigger):导致状态转移的事件 - 动作(Action):状态转移时执行的操作

8.1.2 为什么自动化任务需要状态机

问题:自动化任务在真实环境中会遇到各种异常: - 数据源超时 - API 限流 - 推送失败 - 内容不足

状态机的价值: - 把"如果...怎么办"显式化 - 每个状态有明确的成功出口和失败出口 - 避免"面条代码"式的异常处理 - 易于测试和验证

8.1.3 状态机的核心原则

原则 说明 示例
每个状态必须有进入条件 明确什么情况下进入该状态 定时触发 → Triggered
每个状态必须有成功出口 正常完成的路径 Delivering → Completed
每个状态必须有失败出口 异常处理的路径 Fetching → Blocked
部分失败可继续 不全部阻断 3/4 数据源可用 → 继续聚合

8.2 实战案例:热点选题任务的状态机

8.2.1 完整状态流转图

stateDiagram-v2
    [*] --> Idle
    Idle --> Triggered: 定时/手动触发
    Triggered --> SourceCheck: 开始运行
    SourceCheck --> Fetching: 数据源就绪
    SourceCheck --> Blocked: 数据源不可用(≥2个失败)
    Fetching --> Aggregating: 全部响应
    Fetching --> PartialAggregating: 部分超时
    Aggregating --> Filtering: 聚合完成
    PartialAggregating --> Filtering: 标记缺失后继续
    Filtering --> Delivering: 有效条目≥5条
    Filtering --> Blocked: 有效条目不足
    Delivering --> Completed: 推送成功
    Delivering --> Blocked: 推送失败
    Blocked --> Idle: 告警后等待下次触发
    Completed --> Idle: 完成

8.2.2 状态定义详解

状态 进入条件 成功出口 失败出口 超时阈值
Idle 初始状态/上轮完成 触发后进入 Triggered - -
Triggered 定时触发/手动触发 数据源就绪检查通过 SourceCheck 失败 5秒
SourceCheck 开始运行 ≥3个数据源可用 <3个可用 → Blocked 10秒
Fetching 数据源就绪 全部响应 部分超时 → PartialAggregating 30秒
PartialAggregating 部分超时 标记缺失后继续聚合 全部失败 → Blocked 30秒
Aggregating 全部响应 聚合完成 聚合异常 → Blocked 60秒
Filtering 聚合完成 有效条目≥5条 有效条目不足 → Blocked 30秒
Delivering 过滤完成 推送成功 推送失败 → Blocked 30秒
Completed 推送成功 进入 Idle - -
Blocked 任何状态的失败出口 进入 Idle(次日重试) - -

8.2.3 状态文件设计

{
  "batch_id": "ai-hotspot-2026-07-10",
  "trigger_time": "2026-07-10T09:00:00+08:00",
  "state": "delivering",
  "completed": ["fetching", "aggregating", "filtering"],
  "source_status": {
    "wechat": "ok",
    "github": "ok",
    "multi_search": "ok",
    "aihot": "ok"
  },
  "item_count": 18,
  "last_error": null,
  "updated_at": "2026-07-10T09:02:14+08:00"
}

8.3 实现方式对比

8.3.1 三种实现方式

方式 适用场景 复杂度 灵活性
流程图 + 人工执行 简单任务,手动操作
状态机库(如 XState) 前端/Node.js 应用
自定义状态机 任意环境 中高 最高

8.3.2 Python 实现示例

from enum import Enum
from dataclasses import dataclass
from datetime import datetime

class State(Enum):
    IDLE = "idle"
    TRIGGERED = "triggered"
    SOURCE_CHECK = "source_check"
    FETCHING = "fetching"
    PARTIAL_AGGREGATING = "partial_aggregating"
    AGGREGATING = "aggregating"
    FILTERING = "filtering"
    DELIVERING = "delivering"
    COMPLETED = "completed"
    BLOCKED = "blocked"

@dataclass
class TaskState:
    batch_id: str
    state: State
    completed: list
    source_status: dict
    item_count: int
    last_error: str = None
    updated_at: str = None

class StateMachine:
    def __init__(self, config):
        self.config = config
        self.state = TaskState(
            batch_id=self.generate_batch_id(),
            state=State.IDLE,
            completed=[],
            source_status={},
            item_count=0,
            updated_at=datetime.now().isoformat()
        )

    def transition(self, event):
        """状态转移"""
        current = self.state.state

        # 定义状态转移规则
        transitions = {
            State.IDLE: {
                "trigger": State.TRIGGERED
            },
            State.TRIGGERED: {
                "source_ready": State.SOURCE_CHECK,
                "source_not_ready": State.BLOCKED
            },
            State.SOURCE_CHECK: {
                "ready": State.FETCHING,
                "not_ready": State.BLOCKED
            },
            State.FETCHING: {
                "all_ok": State.AGGREGATING,
                "partial_timeout": State.PARTIAL_AGGREGATING
            },
            State.PARTIAL_AGGREGATING: {
                "continue": State.FILTERING,
                "all_failed": State.BLOCKED
            },
            State.AGGREGATING: {
                "done": State.FILTERING,
                "error": State.BLOCKED
            },
            State.FILTERING: {
                "pass": State.DELIVERING,
                "blocked": State.BLOCKED
            },
            State.DELIVERING: {
                "success": State.COMPLETED,
                "failed": State.BLOCKED
            },
            State.BLOCKED: {
                "retry": State.IDLE,
                "abort": State.IDLE
            },
            State.COMPLETED: {
                "reset": State.IDLE
            }
        }

        # 执行转移
        if event in transitions.get(current, {}):
            new_state = transitions[current][event]
            self.state.state = new_state
            self.state.updated_at = datetime.now().isoformat()
            return True
        return False

8.4 图文说明

📌 待补充:建议绘制以下示意图 1. 状态机完整流程图(10个状态 + 转移箭头) 2. 状态文件结构图 3. 状态转移决策树 4. Python 代码执行流程图


8.5 常见错误

错误 后果 纠正方法
状态定义模糊 难以判断当前状态 每个状态必须有明确的进入条件
缺少失败出口 异常时任务卡住 每个状态都要有失败出口
状态转移无记录 无法排查问题 记录每次转移的事件和时间
状态机过于复杂 难以维护 保持状态数量在合理范围(<15个)
忽略状态持久化 重启后丢失状态 定期保存状态文件

📝 版本迭代记录

版本 日期 更新内容摘要 操作人
v1.0 2026-08-25 创建进阶篇第5章 桂皮
来源:豆包蓝皮书(未声明(社区整理)) · 原文路径 02-进阶篇/05-状态机设计与实现/01-状态机核心概念.md
整理:疯狂的豇豆 · 本站为非官方二次整理,查看完整来源清单
🤖 GEO 问答 · 生成式引擎优化

❓ 什么是状态机设计与实现?


❓ 如何理解实战案例:热点选题任务的状态机?

stateDiagram-v2

❓ 如何理解实现方式对比?

from enum import Enum