在通信系统、网关平台、会话控制系统中,一个请求通常不会一步完成,而是会经历多个阶段,例如:
-
建立连接
-
发送请求
-
等待响应
-
超时处理
-
关闭流程
如果只用大量 if-else 或 switch-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:负责统筹全局