微信扫描登录
或者
请输入您的邮件地址来登录或者创建帐号
提 交取 消
GITBOOK.CN需要您的浏览器打开cookies设置以支持登录功能

通用流程引擎的设计和实现

本篇文章整理自UCloud运营平台总监许杨毅6月30日在『ITA1024运维技术精英群』里的分享实录:通用流程引擎的设计和实现。

enter image description here

概要

FSMG是一个通用流程引擎,能够存储定制化的原始流程拓扑,为拓扑中的节点和连接叠加上业务级别的模型属性。其中,业务模型可以是一个常规的企业内部BPM流程,也可以是一种运维环境下的任务编排流程模型(这是称其为“通用”的原因)。

FSMG内部运作机制是状态+事件的驱动流。其内部有个有限状态机,状态之间的拓扑由图结构定义。同时,FSMG提供webhook+callback RestAPI驱动外部业务系统(跨语言),从而实现不同系统的互操作。这使得其能成为一个独立的,通用外部流程引擎。

FSMG stand for : 有限状态机 + 图。

类似系统: AWS SimpleWorkflow AWS Lambda 泛微OA平台

前言

我们内部有两套流程管理系统A和B。

系统A

A是适用在运维中心内部的,例如资源申请,调拨,回收;以及权限申请,简单运维事务的场合下;B则涉及到跨部门的业务流程上,比如代码上线,在线变更的场合,因此需要牵引研发部门,产品部门,测试部门和业务运维和基础运维一起进入流程中。适用场景的不同决定了在设计上就采用了不同的模型。

A系统,采用了纯粹基于有限状态机的模型,从而其流程特征被弱化了,或则说重点关注了{申请 – 审核 – 执行- 验证 – 结束}这个状态集合。这个设计在初期满足了需求的同时,却也为未来的功能拓展套上了枷锁。

其模型是:

1、定义了一组状态,分别对应于真实业务场景下的“申请”,“提交”,“审批”,“分派”,“执行”,“验证”,“结单”步骤。 注意,是“状态”映射到具体的“步骤”,这其实流程模型向状态机模型妥协的结果。

2、这些状态之下,又设计了一些中间状态来满足一些业务需求(申请后,可以保存草稿);还设计了一些特殊的状态之间的联系来满足特殊的业务需求,比如某些流程,可以不经过审批直接进入执行环节。

A系统的状态机长的像这样:

enter image description here

总结来讲:

模型是一个标准有限状态机,其主干是去掉了“过渡状态”的状态集,“NEWR-AUDIING-EXECUTING-CHECKING-CLOSE”–即“创建,审核,执行,验证,结单”。

优点是:通过状态定义(状态和对应的handler),实现了事件/状态驱动的能力。

缺点是:无法表现更加复杂的流程。例如,具备多个审批环节的流程。具体是通过在AUDITING下增加中间状态APPROVED实现的,另外一个例子是在EXECUTING 中增加中间状态TRANSFERED,onEnter缺省马上回到EXECUTING(事实上已经无法通过模型本身表示与上一个EXECUTING的区别,而要编写逻辑代码实现)。

图中A3,A4,A6,A6.1处显示了业务需求耦合进入模型的痕迹。

系统B

B系统,关注在跨部门的流程协作上,因此一开始就基于流程拓扑进行了业务建模。拓扑以图的形式描述。

建立的流程模型是:

1、流程被定义为flow ,工单被定义为ticket,每个ticket是实例化的flow。

2、流程节点被定义为node,事实上对应了每一个流程中的每个具体步骤。而每个流程节点具备属性如右:{流程中的序号,步骤的名称,步骤对应的关联部门,审批人(缺省为每个部门的主管),操作人,步骤的类型(目前有两种类型 - 先审批后执行,先执行后审批)} 。

3、node对应的数据结构schema就是上述的属性构成的。

4、每个flow由一个或一个以上的node构成,每个flow对应的数据结构实际上是多个Node对象构成的一个有序列表{node1,node2...noden}。每个流程中的各个node具备的“流程中序号”属性,表示了在流程中的位置。从而多个node实际上形成了某一个flow的拓扑。

5、流程中的各个node只有严格的先后祖先关系(每个跨级功能),以及并行关系。(如果两个node 的“流程中序号”相同,则意味着为并行流程。

补充说明:有些情况下,需要有具备跨级属性的node。

关于权限:

flow的权限: 流程创建者拥有创建,修改,删除的权限。

ticket权限:

1、checkman:对某一个ticket进行审批的权限(前提:workman处在激活节点上,否则并没有处理权),添加comment的权限,查看本部门所有工单的权限,查看参与的所有工单的权限,comment参与的所有工单的权限。

2、workman:修改某一个ticket状态(为"finished")的权限(前提:workman处在激活节点上,否则并没有处理权);查看所属本部门所有工单的权限,接管所属本部门所有工单的权限,查看参与的所有工单的权限,comment参与的所有工单的权限。

关于状态:

状态的用途是:

1、触发某个操作 - 处于激活状态的node,要通知该node中的workman 和checkman

2、基于状态进行某个逻辑判断 -- 场景:“我”登录后,进入任意一个(我有权限查看的ticket)后,如果是workman or checkman ,是否是激活node ,是,则检查workman对应的权限;

3、流程状态:流程只是抽象实体,没有状态。

工单状态: 1、工单的状态在实现中,包括了“完成,进行中,被拒绝”,但是并非在ticket表中维护了上诉状态,而是通过业务逻辑判断实现的。

2、工单中的每一个流程步骤的状态的组合决定了,登录上来后的“我”看到的是什么 --> “等待审批,处理完成,执行中”。

3、每个node步骤都需要在其中定义一个status。

总结来讲:

B系统的模型是图结构,而非状态机。图中的节点映射到正式业务流程中的一个具体部门,节点间的有向边则表示了流转方向。某个节点的入边表示前继节点。整体上形成了一个流程的拓扑和节点间的关系。

缺点:没有状态机的定义,状态的定义和流转是编码实现的。因此不具备状态机的“事件+状态驱动“能力。

优点:能够设计成为复杂的流程,流程中节点的定义和属性是可以自定义,可扩展的。比如:{步骤名称,部门,操作类型(注释,审批,执行,代理,转发,操作),内容模板};这一点和A系统的完全不同的。

评估过AB两个系统后,我们发现可以结合两个系统在模型上的优点,也就是:

1、用图结构表述一个流程的抽象拓扑非常合适,拓扑由节点和边之间的关系形成。

2、图结构中的对象Node和Link,可以通过对其属性的不同定义来适用于不同的场景下。

例如:如果node被定义为一个BPM流程的步骤节点,具备{步骤名称,对应部门,操作类型,操作人,内容模板 }则可以表示一个业务流程;如果node 如果被定义为一个运维操作的任务节点,具备{任务名称,执行任务的代码引用路径(可执行代码路径;webhook URL,注册的lambda函数,),代码的参数,callback URL}属性,则可以表示一个任务编排流程。

3、通过有限状态机来实现模型内部/外部的驱动。也就是为为每个抽象的node设计有限状态机,“任务”和“步骤”对应的状态可以作为事件触发后续的流程或者任务,实现event-driven模式,应用到很多业务场景下。并且通过callback来实现任务管理。这一点,lambda仅仅能event-Driven,任务tracking和管理是无法实现的。