基本概念
什么是状态机
定义:包含一组状态集(states)、一个起始状态(start state)、一组输入符号集(context)、一个映射输入符号和当前状态到下一状态的转换函数(action)的计算模型。当输入变量,模型随即进入起始状态。它要改变到新的状态,依赖于转换函数。在有限状态机中,会有有许多变量,例如,状态机有很多与事件关联的动作
行为: 状态机通过响应一系列事件而“运行”。 每个事件都在属于“当前”节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。函数返回“下一个”(也许是同一个)节点。这些节点中至少有一个必须是终态。当到达终态,状态机停止
分类:状态机的分类包括 有限状态机, 层次状态机, 行为树-AI
原理:订单状态机原理主要是根据订单当前的状态去判断可触发哪些事件(Action),对每个可触发的事件作进行check,符合条件的事件则执行相关的逻辑操作。执行完成后将订单状态更新为新的状态,如此循环。
流程中心控制&阶梯式控制
系统整体控制上要采用流程控制中心,而不是阶梯式控制。之前由于直接依赖数据库,数据库最终会成为影响订单处理的瓶颈,数据的一致性很难得到保证,而采用流程控制中心模式则可以大大减少数据不一致发生的几率,同时可以借助工作流和状态机实现中心控制,这样既便于运营,又方便及时发现和解决问题单据.
流程中心控制模式一般使用状态机或者Activity实现。
状态机的特点
应用非常广泛,从有限状态机到层次状态机,在发展到后来的行为树,经久不衰,和Activity很像,同类型的产品,但是比较成熟。
系统模块
状态机主要分为三个模块
状态池
对所有的订单状态进行管理
orderStatus | statusDesc | serviceName | priority |
---|---|---|---|
OS0000 | 初始状态 | SubscribeAction | 0 |
OS0002 | 需求确认 | A | 0 |
OS0002A | B | 1 | |
OS0002G | 占位成功 | C | 1 |
RS0000 | 资源初始化 | D | 1 |
RS0001 | 资源添加 | E | 0 |
RS0002 | F | 6 | |
… | … | … | … |
Action驱动管理
processEngine负责管理每个状态下可触发执行的Action
运行时管理
订单如何根据自动进行状态变迁
流程控制
系统架构
processEngine
描述
状态机的引擎,主要获取或初始化当前状态,当有新订单进来之后,将订单上下文传入状态机,状态机根据上下文初始化订单状态,如果没有订单号,则认为是新建订单,初始化状态,processEngine获取当前状态可执行的Action,驱动可执行Action的执行。
作用
启动状态机,如果是新订单,初始化订单状态
action
状态驱动的业务逻辑单元,当状态机处于某一匹配状态时,可根据Context中的信息执行响应动作
action代表当前订单状态下可执行的操作,启动一个action,首先会通过context校验是否满足当前action的执行条件,如果满足,执行run,执行完之后根据结果判断后续状态的变化。
SubscribeAction
用户提交订单,订单进入状态机,,初始化订单状态,修改当前订单状态为需求确认
当前订单状态 | 可执行Action1 | 可执行Action2 | 可执行Action3 | 可执行action4 |
---|---|---|---|---|
NEED_SURE | distributeOrderAction(0) | distributeOrderFeedAction(1) | orderOccupyAction(2) | orderCancelAction(5) |
需求确认 | 客服分单-分单系统 | 分单回调 | 占位 | 订单取消 |
OrderOccupyAction
action | 可执行Action1 | 可执行Action2 |
---|---|---|
OCCUPY_ING | 添加是否30分钟后添加出游人 | 发起资源占位请求 |
resourceAddAction resourceOccupyAction
资源状态机发起资源占位,各个资源处于占位中,收到确认管理回调,占位成功或者失败。
资源状态 | 可执行Action |
---|---|
初始化 | resourceAddAction |
资源状态 | 可执行Action |
资源已添加 | resourceOccupyAction |
占位成功
改变当前订单状态为占位成功,并重新进入订单引擎,判断当前可执行的操作action有哪些
状态 | 可操作Action1 | 可操作Action2 |
---|---|---|
占位成功 | requireCfmAction(0) | orderReleaseAction(2) |
需求确认对于电话订单,出游人不全的订单,跟团游的订单,出境游的订单,OTA需要确认客人信息,确认底层资源的价格日历,是否有出游人变更等。如果没有这些要求,可直接跳过需求确认。
占位失败
状态 | 可操作Action |
---|---|
占位失败 | orderCancelAction |
需求确认成功
改变订单状态为需求确认成功, 订单重新进入状态机
状态 |可操作Action1 |可操作Action2
–|:–:|:–:
需求确认成功 |signAction(3)| reEntryRequireCfmAction(1)
是否需要重新打开需求确认,如果需要重新打开需求确认,订单状态改变为占位成功
确认confirm
向确认管理发送确认请求, 和占位一样,确认也是按照资源来确认,所有资源回调完成之后,通知订单状态机确认完成。
状态 |可操作Action1 |可操作Action2
–|:–:|:–:
订单确认中 |orderCfmAction(0) |orderCfmFeedBackAction(1)
状态 |可操作Action1 |可操作Action2
确认成功 |orderCfmAction(0) |orderCfmFeedBackAction(1)
还有保险,网上签约,出团,评价
退出状态机
怎么退出引擎,当所有可执行的action执行完之后,跳出第一层action的循环,再判断状态是否发生改变,context中是否要跳出引擎。
action的顺序
订单所有的信息都在context中,可以指定状态机执行特定的action,如果指定action,则引擎只执行这个action,如果没有指定,执行所有action。被执行的所有Action都是有优先级的。
插件化配置
对于状态机新增一个action,相当于activity新增一个流程,我们只需在数据库配置流程编号,流程编码,动作名等。热插拔!
Context
状态机运行的上下文,与外部服务交互的数据接口,外部服务可将Action执行所需业务参数注入,提供给Action执行时使用。 正在执行的状态的Context需要包含订单号、订单状态、Action执行所需参数等信息。
对象时序图