1 什么是流程引擎

流程引擎是一个底层撑持平台,是为提供流程解决而开发设计的。流程引擎和流程利用,以及应用程序的关系如下图所示。

常见的撑持场景有:Workflow、BPM、流程编排等。本次分享,次要从BPM流程引擎切入,介绍流程引擎的架构设计办法。

1.1 什么是流程

简略来说,流程就是一系列流动的组合。比方,用于企业办公的OA零碎中,就存在大量的申请审批类的流程。在生产制造业,有大量的从销售端的订单,到生产制作,再到签收回款的生产销售流程。在机器学习畛域,有亚马逊AWS Sagemaker的大数据处理、机器学习的利用。综上,流程是一个概念,在和具体实现联合时,就产生了不同的流程产品,如DevOps、Spring Data Stream等。
在流程实现方面,次要能够分为2种实现形式,一种是用代码实现,比方:用代码实现一个加班申请,那么就要本人对接SSO进行单点登录,通过接口拿到发起人和审批人的信息,同时保留表单数据。另一种形式是应用流程引擎来实现,流程引擎对接利用场景所需数据,如加班申请,流程引擎对接SSO、OU、审批人配置、权限等,实现这样一个流程,只须要关怀流程配置、流程节点和流程表单即可,流程流转以及流程的数据处理,都通过流程引擎来实现。
流程引擎能够疾速落地流程实现,这也是流程引擎存在的价值。

1.2 什么是引擎

一般而言,引擎是一个程序或一套零碎的反对局部。常见的程序引擎有游戏引擎、搜索引擎、杀毒引擎等。引擎是脱离具体业务场景的某一类业务场景的高度形象和封装。
比方,某OA公司,封装了一套审批用的workflow,施行人员只须要配置流程和表单即可交付我的项目。再比方,美国某公司做了一个AI引擎做NBA(Next Best Action)举荐,封装了举荐畛域的罕用算法,在不同的场景主动抉择和组合多种算法,进行智能举荐。

1.3 流程设计器

流程设计器是流程和引擎的连贯方,用户通过流程设计器,将某种layout和rule固化成某种流程,而后通过数据和数据上下文,应用流程引擎主动依照某种固化的流程进行执行。
我将目前见到的流程设计器的实践根底,分为以下三类:1,自定义系;2,UML中的流动图系;3,BPMN系。

1.3.1 自定义系

用于Sagemaker等场景的AWS Step Function(自定义流程节点)

1.3.2 UML Activity Diagram

Flowportal BPM的流程设计器

1.3.3 BPMN系

activiti的流程设计器

炎黄盈动的流程设计器

题外话:炎黄盈动的流程设计器,和processon中的流程设计器界面简直一样,因为实质上是一家的。

2 流程引擎的利用

2.1 Workflow

工作流治理联盟(Workflow Management Coalition,WfMC)作为工作流治理的标准化组织而成立。
WfMC对工作流给出定义为:工作流是指一类可能齐全主动执行的经营过程,依据一系列过程规定,将文档、信息或工作在不同的执行者之间进行传递与执行。

在workflow中,流程引擎次要用于撑持流程审批和数据流转,利用场景十分宽泛。
国外产品(开源或商用)通常需要和操作比较简单,不会有国内的需要那么简单。国内的产品,经验了泛滥客户的锻炼,性能目前都比拟弱小。
一般而言,workflow应用场景最多的是OA产品。在OA办公中,蕴含了企业办公中的大量元素,这些元素足够造成特定的产品,比方门户零碎、挪动办公。在OA的我的项目落地过程中,联合行业、业务侧重点又能够造成行业解决方案和专题计划。
以下是某OA公司产品和解决方案。

2.2 BPM(Business Process Management)

Workflow次要是解决审批和数据流转,而BPM次要是解决端到端、信息孤岛等问题而存在的。大多数用BPM产品的客户,都是在BPM根底上进行零碎搭建,比方在BPM下面搭建OA、CRM、HR等零碎。
BPM的应用场景,比Workflow更宽泛,BPM产品中蕴含大量的和第三方零碎交互的组件和自定义SQL、代码组件。比方,BPM零碎中的文件触发器,能够在海关等交互场景下,通过监控FTP服务器中的文件,主动触发流程实例;能够通过定时器Timer,主动每日执行数据同步,并通过Mail节点将同步后果告诉到相干经营成员等。

BPM的利用,能够依照执行前、执行中和执行起初划分。

2.3 流程编排

流程编排是脱离流程业务畛域的更高一层形象,应用方能够通过流程编排零碎,联合本人的业务场景进行业务定制。比方,能够将相干业务代码,封装成function,而后通过云厂商平台的FAAS平台,将不同业务的function进行关联和调度,从而实现某项工作。

3 流程引擎的架构设计

鉴于一些敌人可能没有应用和接触过流程引擎,先介绍流程引擎的组成单元,再介绍基于某个BPM产品的我的项目是如何进行开发的。咱们通过BPM我的项目开发,对流程引擎的作用有个初步的意识。

3.1 BPM流程引擎的组成单元

  1. 组织、角色、用户、成员的组织架构托管;
  2. 流程资源文件的配置、校验、存储和执行,对不同的流程节点,流程引擎主动联合配置、数据处理其对应的业务逻辑,流程数据主动解决;
  3. 表单配置、数据绑定,表单数据的依据流程配置主动解决;
  4. 通用的数据接口;

3.1.1 组织架构的设计

3.1.2 流程设计器

流程设计器蕴含左侧的分组节点列表,和右侧的画布。左侧的节点能够如下进行设计。

问题:对于一个XML或JSON格局的流程图,如何进行解析?
不同的节点,依照不同的业务场景,配置不同的配置项。比方,对于Human Node须要配置审批人,配置审批环节的展现表单,审批环节可能批改哪些字段,哪些字段的批改要进行留痕等。

3.1.3 表单设计器

这种是依照表单相干数据表,生成出一个表单,而后对表单字段进行配置和数据绑定。

这种是Drag&Drop控件,而后配置控件的属性,如绑定字段等。

这种是Drag&Drop控件,无需关联数据库表字段的表单

数据表生成表单的概要流程如下图所示。

拖拽控件绑定数据表字段的概要流程如下。

拖拽控件无需绑定数据表字段的概要流程。应用NoSQL的Document记录或应用RDS提供的JSON类型进行保留会比拟不便。

3.1.4 接口设计

联合Activity的接口设计,如下图所示

一些零碎在创立一个流程工作的时候,要先依照流程模板先创立一个利用示例,再关联发起人和备注,调用RuntimeService,执行到StartNode,这类设计因人而异,这么做略显繁琐。

3.2 基于流程引擎的我的项目开发实际

3.2.1 流程我的项目实际流程

  1. 确定组织架构
  2. 确定流程,包含流程布局、审批人设置、权限
  3. 确定表单信息(字段、类型、数据源、校验规定)和表单款式
  4. 确定页面布局、款式、数据字段、搜寻、导入、导出
  5. 报表

3.2.2 组织架构

组织架构实现,有两种办法,一种是依照维度进行数据管理,另一种是在同一棵组织架构树下进行治理。
依照团体、公司、部门、用户等不同维度,进行数据管理,比拟常见,这里不做探讨。下图为按维度保护数据的示例。

依照同一棵组织架构树进行数据保护,界面个别显示为左树右表。大多数商业化产品,都会将此组织架构树进行内存缓存,以不便审批人查找、开窗抉择OrgUnit、Role、User、Member等场景。Member的引入是为了解决一人多职等场景。个别发动流程的时候,须要带出发起人领有的Member列表,从而后续节点取适合的审批人。

对于组织架构而言,须要思考,零碎自身要具备OU存储的能力,对于没有组织架构的用户,能够间接在零碎的组织架构中新建组织架构。同时,对于已有零碎的客户,能够通过组织架构数据同步来进行数据主动保护。对于用AD域外部管控的客户来说,须要具备AD域身份认证的能力。对于简单场景,比方用户是SaaS化等简单场景,组织架构也须要在零碎外部,反对应用API的形式来获取组织信息。
所以在组织架构设计的时候,要应用插件的形式来做,具体应用哪种插件,能够在配置文件中进行配置。以下为一个商业产品的组织架构操作界面示例。

常见的组织架构操作还有组织架构同步,比方流程零碎同步微信企业号、钉钉等,这里不再开展。

3.2.3 流程设计

咱们设想的流程,可能是向上面的这种简略流程。

而理论我的项目,碰到的流程,个别是如下图所示的情景。

初步看几个流程的模型文件是什么样的,先有个印象。

<?xml version="1.0" encoding="UTF-8" ?><definitions id="definitions"targetNamespace="http://activiti.org/bpmn20"xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:activiti="http://activiti.org/bpmn"><process id="vacationRequest" name="Vacation request"><startEvent id="request" activiti:initiator="employeeName"><extensionElements><activiti:formProperty id="numberOfDays" name="Number of days" type="long" value="1" required="true"/><activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" /><activiti:formProperty id="vacationMotivation" name="Motivation" type="string" /></extensionElements></startEvent><sequenceFlow id="flow1" sourceRef="request" targetRef="handleRequest" /><userTask id="handleRequest" name="Handle vacation request" ><documentation>${employeeName} would like to take ${numberOfDays} day(s) of vacation (Motivation: ${vacationMotivation}).</documentation><extensionElements><activiti:formProperty id="vacationApproved" name="Do you approve this vacation" type="enum" required="true"><activiti:value id="true" name="Approve" /><activiti:value id="false" name="Reject" /></activiti:formProperty><activiti:formProperty id="managerMotivation" name="Motivation" type="string" /></extensionElements><potentialOwner><resourceAssignmentExpression><formalExpression>management</formalExpression></resourceAssignmentExpression></potentialOwner></userTask><sequenceFlow id="flow2" sourceRef="handleRequest" targetRef="requestApprovedDecision" /><exclusiveGateway id="requestApprovedDecision" name="Request approved?" /><sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail"><conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'true'}</conditionExpression></sequenceFlow><task id="sendApprovalMail" name="Send confirmation e-mail" /><sequenceFlow id="flow4" sourceRef="sendApprovalMail" targetRef="theEnd1" /><endEvent id="theEnd1" /><sequenceFlow id="flow5" sourceRef="requestApprovedDecision" targetRef="adjustVacationRequestTask"><conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'false'}</conditionExpression></sequenceFlow><userTask id="adjustVacationRequestTask" name="Adjust vacation request"><documentation>Your manager has disapproved your vacation request for ${numberOfDays} days.Reason: ${managerMotivation}</documentation><extensionElements><activiti:formProperty id="numberOfDays" name="Number of days" value="${numberOfDays}" type="long" required="true"/><activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" value="${startDate}" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" /><activiti:formProperty id="vacationMotivation" name="Motivation" value="${vacationMotivation}" type="string" /><activiti:formProperty id="resendRequest" name="Resend vacation request to manager?" type="enum" required="true"><activiti:value id="true" name="Yes" /><activiti:value id="false" name="No" /></activiti:formProperty></extensionElements><humanPerformer><resourceAssignmentExpression><formalExpression>${employeeName}</formalExpression></resourceAssignmentExpression></humanPerformer></userTask><sequenceFlow id="flow6" sourceRef="adjustVacationRequestTask" targetRef="resendRequestDecision" /><exclusiveGateway id="resendRequestDecision" name="Resend request?" /><sequenceFlow id="flow7" sourceRef="resendRequestDecision" targetRef="handleRequest"><conditionExpression xsi:type="tFormalExpression">${resendRequest == 'true'}</conditionExpression></sequenceFlow><sequenceFlow id="flow8" sourceRef="resendRequestDecision" targetRef="theEnd2"><conditionExpression xsi:type="tFormalExpression">${resendRequest == 'false'}</conditionExpression></sequenceFlow><endEvent id="theEnd2" /></process></definitions>

一个屏幕截图都截不完的流程,如果用代码去实现整个流程,其工作量和效率,可想而知。而理论做我的项目,应用基于流程引擎的产品来做我的项目的时候,只须要确定节点、节点配置、数据配置和权限即可。
问题:个别流程,都带有邮件告诉的节点,如何实现邮件告诉节点?请思考以下情景。
流程流转和执行的时候,会遇到各种状况的谬误,比方找不到审批人等,此时流程引擎要对数据做rollback,而邮件告诉节点的业务逻辑曾经执行过了。

权限方面,对于流程资源,哪些部门能够申请,哪些角色不可申请,都应该做流程管制。而在流程执行过程中,流程数据、不是途程的相干人也都不应该看到流程,解决过流程的审批人,不能够再对流程进行解决等,都是权限方面要思考的问题。

3.2.4 表单设计

如下图所示的表单,能够剖析以下,一个流程表单有多个主表信息和多个子表信息。一般而言,如果是通过流程引擎做非流程的数据处理,子表通过主表ID来做关联,如果通过流程引擎做流程的数据处理,子表和主表通过TaskId来做关联。以下为示例。

流程零碎须要表单设计器,一个流程的不同节点能够挂接不同的表单,以不便不同角色的人关注不同维度的流程信息

3.2.5 页面设计

一般而言,对于流程的发动、审批、历史记录等,都是通用的零碎界面。而一些业务场景,须要独自做列表界面,以方便使用。对于已有门户零碎的客户,须要交融其界面款式。以下为已经做过的我的项目示例。

3.2.6 报表

因为不是所有客户都有报表零碎,所以流程零碎须要具备一个根本的报表性能。下图为示例。

有报表零碎的客户,能够应用其商业版报表零碎,获取(间接取、数仓)数据进行展现。常见的报表零碎有FineReport、Tableau、PowerBI等。

3.3 BPM流程引擎架构设计

3.3.1 流程引擎的架构设计

3.3.2 发动流程

流程引擎处理过程

执行节点处理过程

问题:在流程引擎处理过程中,如果一个节点有多条连线,如何寻找FromNodeId是某个Node的连线?
人工解决时,指定连线text

3.4 流程引擎架构设计

3.4.1 业务辨认

  1. 辨认业务场景中的配置项,应用汇合或分组的形式,让业务可配置
  2. 撑持业务流程过程的可配置化
  3. 撑持业务场景中的数据,主动解决

3.4.2 流程引擎的实现

  1. 资源相干服务,资源加载,资源保留,资源加密等
  2. 配置项相干服务
  3. PVM虚拟机的实现,即通过某个节点(发动时为开始节点)作为初始节点,依照某个连线的action进行节点的主动执行的虚拟机
  4. 数据配置、数据权限
  5. 流程数据和业务数据的主动解决

4 商业机会

  1. Business Process Analysis (BPA) 流程剖析,帮忙企业进行流程调整和优化
  2. Process Assets Library(PAL)流程资产库,对企业流程进行知识化积淀,将制度和流程落地做绑定,让审批人通晓流程中对应的职责
  3. Process Simulate 流程模仿,自动化测试
  4. Process Forecast 流程预测
  5. 低代码平台
  6. 更宽泛的机会,在于业务畛域+流程引擎,比方:DevOps、RPA、利用与服务编排、数据编排、FaaS编排等。

作者:马瑞