从零实现通信级FSM框架:三层状态机架构设计与实践

4 阅读4分钟

在通信系统、网关平台、会话控制系统中,一个请求通常不会一步完成,而是会经历多个阶段,例如:

  • 建立连接

  • 发送请求

  • 等待响应

  • 超时处理

  • 关闭流程

如果只用大量 if-elseswitch-case 管理,很容易出现代码混乱、状态爆炸、维护困难的问题。

因此,工业级系统通常会设计一套分层状态机框架,将复杂流程拆分成不同职责层级。


一、整体架构通俗理解

可以把整个系统想象成一家大型医院:

  • Cfsm:单个病人,每个人有自己的就诊流程

  • Cfactory:科室,负责管理很多病人

  • Cfactory_mgr:医院总控中心,负责全局调度和资源管理

                外部请求/消息
                      ↓
         ┌─────────────────────┐
         │   Cfactory_mgr      │
         │ 总调度 / 消息泵 / 资源池 │
         └─────────────────────┘
                      ↓
         ┌─────────────────────┐
         │      Cfactory       │
         │ FSM管理 / 路由 / 生命周期 │
         └─────────────────────┘
                      ↓
         ┌─────────────────────┐
         │        Cfsm         │
         │ 状态处理 / 消息处理   │
         └─────────────────────┘

这三层结构的核心思想是:

Cfsm负责执行具体业务,Cfactory负责管理FSM实例,Cfactory_mgr负责全局协调资源。


二、Cfsm:真正处理业务流程的状态机实例

Cfsm 是最底层的执行单元,每个实例通常代表一个独立业务流程,例如:

用户注册流程:
INIT → CONNECT → REQ → RESP → CLOSE

核心职责

  • 保存当前状态 _state

  • 根据收到的消息决定状态转移

  • 暂存暂时无法处理的消息

  • 调用定时器、发送消息

简化代码示例

class RegFsm : public Cfsm
{
public:
    EerrNo ProcessMsg(CMsg& msg) override
    {
        switch (msg.type)
        {
            case MSG_INIT:
                SetState(WORKING);
                msg.type = MSG_CONNECT;
                break;

            case MSG_CONNECT:
                msg.type = MSG_REQ;
                break;

            case MSG_REQ:
                msg.type = MSG_RESP;
                break;

            case MSG_RESP:
                msg.type = MSG_CLOSE;
                break;

            case MSG_CLOSE:
                SetState(KILL_FSM);
                break;
        }

        return SUCCESS;
    }
};

消息处理流程图

收到消息
   ↓
PrePrcMsg(预处理)
   ↓
ProcessMsg(状态切换)
   ↓
PostPrcMsg(收尾处理)

通俗理解

Cfsm 就像一个“具体员工”:

  • 自己知道当前工作进度

  • 收到任务后决定下一步

  • 完成后结束流程


三、Cfactory:FSM工厂与业务调度中心

如果系统里同时有几千个用户流程,不可能只靠单个 FSM。

因此需要 Cfactory 来统一管理同类型 FSM。

例如:

  • 注册业务工厂

  • 呼叫业务工厂

  • 会话业务工厂

核心职责

  • 创建新的 FSM

  • 保存多个 FSM 实例

  • 根据消息找到对应 FSM

  • 回收结束的 FSM

工作流程图

新消息到达
    ↓
判断属于哪个业务类型
    ↓
查找是否已有对应FSM
   ↓         ↓
有FSM       无FSM
 ↓            ↓
转发        新建FSM

简化代码示例

class RegFactory : public Cfactory
{
public:
    Cfsm* _facMsgPrc(CMsg& msg) override
    {
        if (!FindFsm(msg))
        {
            return CreateFsm();
        }

        return FindFsm(msg);
    }
};

通俗理解

Cfactory 像“部门主管”:

  • 哪个任务给谁做

  • 新员工什么时候入职

  • 哪个员工该离职


四、Cfactory_mgr:全局调度器与资源池核心

这是整个系统最核心的一层,相当于“操作系统内核”。

核心职责

  • 接收外部所有消息

  • 提供消息队列(消息泵)

  • 管理消息缓冲区池

  • 管理定时器池

  • 管理所有 Factory

  • 多线程安全控制

工作流程图

外部网络消息
      ↓
SendMsg进入消息泵
      ↓
_taskEntry主循环
      ↓
解析消息类型
      ↓
找到对应Factory
      ↓
Factory找到对应FSM
      ↓
FSM处理消息

简化代码示例

void Cfactory_mgr::_taskEntry()
{
    while (true)
    {
        CMsg msg = _pump.Pop();

        Cfactory* fac = FindFactory(msg);

        if (fac)
        {
            fac->Process(msg);
        }
    }
}

通俗理解

Cfactory_mgr 像“医院总控台”:

  • 所有病人先进入总台

  • 总台分发到对应科室

  • 统一调度资源

  • 控制整体运行效率


五、完整协作流程(最重要)

整个系统运行流程如下:

1. 外部消息进入系统
        ↓
2. Cfactory_mgr 接收并放入消息泵
        ↓
3. Cfactory_mgr 找到对应 Cfactory
        ↓
4. Cfactory 决定交给哪个 Cfsm
        ↓
5. Cfsm 根据状态处理消息
        ↓
6. 流程结束则回收FSM

六、设计模式分析

工厂模式(Factory Pattern)

  • Cfactory 创建和管理 FSM

  • 降低对象创建耦合

状态模式(State Pattern)

  • Cfsm 不同状态执行不同逻辑

  • 状态迁移清晰

资源池模式(Object Pool Pattern)

  • Cfactory_mgr 管理消息buffer与timer

  • 避免频繁申请释放内存


七、为什么这种架构适合高并发通信系统?

相比普通写法:

switch + if + 全局变量

分层FSM框架优势明显:

  • 模块化

  • 易扩展

  • 高并发支持

  • 生命周期清晰

  • 内存利用率高

  • 更适合复杂协议控制

典型应用场景

  • SIP协议栈

  • Diameter

  • 核心网会话控制

  • 电力通信下行系统

  • 网关服务


八、总结

这套架构的本质不是单纯“写状态机”,而是:

通过分层设计,将复杂业务流程、资源管理、并发调度系统化。

一句话理解:

  • Cfsm:负责干活

  • Cfactory:负责管FSM

  • Cfactory_mgr:负责统筹全局