订单状态机实践

基本概念

什么是状态机

定义:包含一组状态集(states)、一个起始状态(start state)、一组输入符号集(context)、一个映射输入符号和当前状态到下一状态的转换函数(action)的计算模型。当输入变量,模型随即进入起始状态。它要改变到新的状态,依赖于转换函数。在有限状态机中,会有有许多变量,例如,状态机有很多与事件关联的动作

行为: 状态机通过响应一系列事件而“运行”。 每个事件都在属于“当前”节点的转移函数的控制范围内,其中函数的范围是节点的一个子集。函数返回“下一个”(也许是同一个)节点。这些节点中至少有一个必须是终态。当到达终态,状态机停止

分类:状态机的分类包括 有限状态机, 层次状态机, 行为树-AI

原理:订单状态机原理主要是根据订单当前的状态去判断可触发哪些事件(Action),对每个可触发的事件作进行check,符合条件的事件则执行相关的逻辑操作。执行完成后将订单状态更新为新的状态,如此循环。

流程中心控制&阶梯式控制

avatar

系统整体控制上要采用流程控制中心,而不是阶梯式控制。之前由于直接依赖数据库,数据库最终会成为影响订单处理的瓶颈,数据的一致性很难得到保证,而采用流程控制中心模式则可以大大减少数据不一致发生的几率,同时可以借助工作流和状态机实现中心控制,这样既便于运营,又方便及时发现和解决问题单据.
流程中心控制模式一般使用状态机或者Activity实现。

状态机的特点

应用非常广泛,从有限状态机到层次状态机,在发展到后来的行为树,经久不衰,和Activity很像,同类型的产品,但是比较成熟。

系统模块

状态机主要分为三个模块
avatar

状态池

对所有的订单状态进行管理

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

运行时管理

订单如何根据自动进行状态变迁

流程控制

avatar

系统架构

avatar

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执行所需参数等信息。

对象时序图

avatar