您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
流程引擎的架构设计
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
流程引擎的架构设计
自猿其说Tech
2022-07-21
IP归属:未知
433560浏览
### 1 什么是流程引擎 流程引擎是一个底层支撑平台,是为提供流程处理而开发设计的。流程引擎和流程应用,以及应用程序的关系如下图所示。 ![](//img1.jcloudcs.com/developer.jdcloud.com/195d2868-2dcc-45f0-98d6-486ee5b18f4f20220721190151.png) 常见的支撑场景有: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(自定义流程节点) ![](//img1.jcloudcs.com/developer.jdcloud.com/2ab8e767-603b-49ef-a771-7786e96168ff20220721190227.png) ##### 1.3.2 UML Activity Diagram Flowportal BPM的流程设计器 ![](//img1.jcloudcs.com/developer.jdcloud.com/3a365416-02f9-4eea-9b93-f587a21be48920220721190240.png) ##### 1.3.3 BPMN系 activiti的流程设计器 ![](//img1.jcloudcs.com/developer.jdcloud.com/e410cbc3-a518-49ba-a968-fed123bc093d20220721190253.png) 炎黄盈动的流程设计器 ![](//img1.jcloudcs.com/developer.jdcloud.com/a1d01ca2-1ade-44fd-a776-79ff3dbb5ca620220721190307.png) 题外话:炎黄盈动的流程设计器,和processon中的流程设计器界面几乎一样,因为本质上是一家的。 ### 2 流程引擎的应用 #### 2.1 Workflow 工作流管理联盟(Workflow Management Coalition,WfMC)作为工作流管理的标准化组织而成立。 WfMC对工作流给出定义为:工作流是指一类能够完全自动执行的经营过程,根据一系列过程规则,将文档、信息或任务在不同的执行者之间进行传递与执行。 ![](//img1.jcloudcs.com/developer.jdcloud.com/d8cee1d5-9a52-450b-8ddc-7f325551fccd20220721190516.png) 在workflow中,流程引擎主要用于支撑流程审批和数据流转,应用场景非常广泛。 国外产品(开源或商用)通常需求和操作比较简单,不会有国内的需求那么复杂。国内的产品,经历了众多客户的锤炼,功能目前都比较强大。 一般而言,workflow使用场景最多的是OA产品。在OA办公中,包含了企业办公中的大量元素,这些元素足够形成特定的产品,比如门户系统、移动办公。在OA的项目落地过程中,结合行业、业务侧重点又可以形成行业解决方案和专题方案。 以下是某OA公司产品和解决方案。 ![](//img1.jcloudcs.com/developer.jdcloud.com/f8415b52-c267-4a7b-9bd1-94805353ed8f20220721190530.png) #### 2.2 BPM(Business Process Management) Workflow主要是解决审批和数据流转,而BPM主要是解决端到端、信息孤岛等问题而存在的。大多数用BPM产品的客户,都是在BPM基础上进行系统搭建,比如在BPM上面搭建OA、CRM、HR等系统。 BPM的使用场景,比Workflow更广泛,BPM产品中包含大量的和第三方系统交互的组件和自定义SQL、代码组件。比如,BPM系统中的文件触发器,可以在海关等交互场景下,通过监控FTP服务器中的文件,自动触发流程实例;可以通过定时器Timer,自动每日执行数据同步,并通过Mail节点将同步结果通知到相关运营成员等。 ![](//img1.jcloudcs.com/developer.jdcloud.com/44faa3fb-8318-4d89-913d-59871c5712d120220721190548.png) ![](//img1.jcloudcs.com/developer.jdcloud.com/70f7932f-0556-4d31-83ba-a67eeee4e77820220721190554.png) BPM的应用,可以按照执行前、执行中和执行后来划分。 ![](//img1.jcloudcs.com/developer.jdcloud.com/fec79a78-4c77-4243-9599-a1696aa6fd3920220721190608.png) #### 2.3 流程编排 流程编排是脱离流程业务领域的更高一层抽象,使用方可以通过流程编排系统,结合自己的业务场景进行业务定制。比如,可以将相关业务代码,封装成function,然后通过云厂商平台的FAAS平台,将不同业务的function进行关联和调度,从而完成某项任务。 ### 3 流程引擎的架构设计 鉴于一些朋友可能没有使用和接触过流程引擎,先介绍流程引擎的组成单元,再介绍基于某个BPM产品的项目是如何进行开发的。我们通过BPM项目开发,对流程引擎的作用有个初步的认识。 #### 3.1 BPM流程引擎的组成单元 1. 组织、角色、用户、成员的组织架构托管; 2. 流程资源文件的配置、校验、存储和执行,对不同的流程节点,流程引擎自动结合配置、数据处理其对应的业务逻辑,流程数据自动处理; 3. 表单配置、数据绑定,表单数据的根据流程配置自动处理; 4. 通用的数据接口; ##### 3.1.1 组织架构的设计 ![](//img1.jcloudcs.com/developer.jdcloud.com/4ffe1507-bffb-444d-9775-5808a2c26be820220721200058.png) ##### 3.1.2 流程设计器 流程设计器包含左侧的分组节点列表,和右侧的画布。左侧的节点可以如下进行设计。 ![](//img1.jcloudcs.com/developer.jdcloud.com/0d602304-395f-43f0-bb01-62b3ad6ec4bd20220721200121.png) **问题:对于一个XML或JSON格式的流程图,如何进行解析?** 不同的节点,按照不同的业务场景,配置不同的配置项。比如,对于Human Node需要配置审批人,配置审批环节的展示表单,审批环节能够修改哪些字段,哪些字段的修改要进行留痕等。 ##### 3.1.3 表单设计器 ![](//img1.jcloudcs.com/developer.jdcloud.com/e9d24917-afd7-453d-8bab-979f62e7e9da20220721200134.png) ![](//img1.jcloudcs.com/developer.jdcloud.com/bcd0a065-08c3-4bdf-a9c9-ff7c7998e54620220721200147.png) 这种是按照表单相关数据表,生成出一个表单,然后对表单字段进行配置和数据绑定。 ![](//img1.jcloudcs.com/developer.jdcloud.com/5b084e8d-e3e3-4696-8a2d-edfb5e0bc64a20220721200159.png) ![](//img1.jcloudcs.com/developer.jdcloud.com/f3715735-d51a-4b69-9bc5-4b916eb3cb1720220721200211.png) 这种是Drag&Drop控件,然后配置控件的属性,如绑定字段等。 ![](//img1.jcloudcs.com/developer.jdcloud.com/8a309588-e3ba-480a-aa05-8b05b12878d920220721200228.png) 这种是Drag&Drop控件,无需关联数据库表字段的表单 ![](//img1.jcloudcs.com/developer.jdcloud.com/6654a811-1f7c-41f3-80e0-938f6a35b0a220220721200238.png) 数据表生成表单的概要流程如下图所示。 ![](//img1.jcloudcs.com/developer.jdcloud.com/a9ab5820-b2a7-4419-9ad2-798f333b8e0d20220721200247.png) 拖拽控件绑定数据表字段的概要流程如下。 ![](//img1.jcloudcs.com/developer.jdcloud.com/1a15c80c-37ab-4998-9237-cdec121466dd20220721200425.png) 拖拽控件无需绑定数据表字段的概要流程。使用NoSQL的Document记录或使用RDS提供的JSON类型进行保存会比较方便。 ![](//img1.jcloudcs.com/developer.jdcloud.com/5eb984cb-f644-4e53-a0a2-78ba45dfc3df20220721200435.png) ##### 3.1.4 接口设计 结合Activity的接口设计,如下图所示 ![](//img1.jcloudcs.com/developer.jdcloud.com/ec165791-90b7-449a-b727-7aea61df8fce20220721200613.png) 一些系统在创建一个流程任务的时候,要先按照流程模板先创建一个应用示例,再关联发起人和备注,调用RuntimeService,执行到StartNode,这类设计因人而异,这么做略显繁琐。 #### 3.2 基于流程引擎的项目开发实践 ##### 3.2.1 流程项目实践流程 1. 确定组织架构 2. 确定流程,包括流程布局、审批人设置、权限 3. 确定表单信息(字段、类型、数据源、校验规则)和表单样式 4. 确定页面布局、样式、数据字段、搜索、导入、导出 5. 报表 ##### 3.2.2 组织架构 组织架构实现,有两种方法,一种是按照维度进行数据管理,另一种是在同一棵组织架构树下进行管理。 按照集团、公司、部门、用户等不同维度,进行数据管理,比较常见,这里不做讨论。下图为按维度维护数据的示例。 ![](//img1.jcloudcs.com/developer.jdcloud.com/14e1fafe-7461-4d03-b42e-ec05bf82490920220721200652.png) 按照同一棵组织架构树进行数据维护,界面一般显示为左树右表。大多数商业化产品,都会将此组织架构树进行内存缓存,以方便审批人查找、开窗选择OrgUnit、Role、User、Member等场景。Member的引入是为了解决一人多职等场景。一般发起流程的时候,需要带出发起人拥有的Member列表,从而后续节点取合适的审批人。 ![](//img1.jcloudcs.com/developer.jdcloud.com/121dfd67-da98-407b-a3cc-cb3e01cca95120220721200840.png) 对于组织架构而言,需要考虑,系统本身要具备OU存储的能力,对于没有组织架构的用户,可以直接在系统的组织架构中新建组织架构。同时,对于已有系统的客户,可以通过组织架构数据同步来进行数据自动维护。对于用AD域内部管控的客户来说,需要具备AD域身份认证的能力。对于复杂场景,比如用户是SaaS化等复杂场景,组织架构也需要在系统内部,支持使用API的方式来获取组织信息。 所以在组织架构设计的时候,要使用插件的方式来做,具体使用哪种插件,可以在配置文件中进行配置。以下为一个商业产品的组织架构操作界面示例。 ![](//img1.jcloudcs.com/developer.jdcloud.com/0c424e5a-e5a0-4407-905b-203b4239b54920220721200855.png) 常见的组织架构操作还有组织架构同步,比如流程系统同步微信企业号、钉钉等,这里不再展开。 ##### 3.2.3 流程设计 我们想象的流程,可能是向下面的这种简单流程。 ![](//img1.jcloudcs.com/developer.jdcloud.com/ab07af2b-aaaf-498f-b3df-71bec6ba1d4920220721200911.png) 而实际项目,碰到的流程,一般是如下图所示的情景。 ![](//img1.jcloudcs.com/developer.jdcloud.com/48a78007-667c-4f15-820d-264f6848de5020220721200922.png) 初步看几个流程的模型文件是什么样的,先有个印象。 ![](//img1.jcloudcs.com/developer.jdcloud.com/474fbaf7-ce59-4ea3-881d-d6d5c18efee320220721200933.png) ```xml <?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来做关联。以下为示例。 ![](//img1.jcloudcs.com/developer.jdcloud.com/343f616f-51f3-4591-b822-9d944952e65e20220721201004.png) 流程系统需要表单设计器,一个流程的不同节点可以挂接不同的表单,以方便不同角色的人关注不同维度的流程信息 ##### 3.2.5 页面设计 一般而言,对于流程的发起、审批、历史记录等,都是通用的系统界面。而一些业务场景,需要单独做列表界面,以方便使用。对于已有门户系统的客户,需要融合其界面样式。以下为曾经做过的项目示例。 ![](//img1.jcloudcs.com/developer.jdcloud.com/a75f68b0-3fcf-44eb-bfa4-b68a497250c220220721201024.png) ![](//img1.jcloudcs.com/developer.jdcloud.com/550f3646-adea-4d19-a4a6-15fd382a3f4920220721201033.png) ##### 3.2.6 报表 由于不是所有客户都有报表系统,所以流程系统需要具备一个基本的报表功能。下图为示例。 ![](//img1.jcloudcs.com/developer.jdcloud.com/9b723bca-fdd7-4ea7-9cbe-1f24001eaf9520220721201050.png) 有报表系统的客户,可以使用其商业版报表系统,获取(直接取、数仓)数据进行展示。常见的报表系统有FineReport、Tableau、PowerBI等。 #### 3.3 BPM流程引擎架构设计 ##### 3.3.1 流程引擎的架构设计 ![](//img1.jcloudcs.com/developer.jdcloud.com/27a03c1c-616d-42e6-b4f5-1ae92ef32d7320220721201118.png) ##### 3.3.2 发起流程 ![](//img1.jcloudcs.com/developer.jdcloud.com/19f86ad4-2921-400f-8232-64ef47e2119d20220721201212.png) 流程引擎处理过程 ![](//img1.jcloudcs.com/developer.jdcloud.com/1f1a864f-a484-461e-9141-fd6bdcecb81320220721201222.png) 执行节点处理过程 ![](//img1.jcloudcs.com/developer.jdcloud.com/55f89a3a-0076-4613-863e-6f9a0bb0849220220721201233.png) 问题:在流程引擎处理过程中,如果一个节点有多条连线,如何寻找FromNodeId是某个Node的连线? 人工处理时,指定连线text #### 3.4 流程引擎架构设计 ![](//img1.jcloudcs.com/developer.jdcloud.com/40194f1f-778f-4d10-8a33-e1f70a43d46720220721201252.png) ##### 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. 低代码平台 更广泛的机会,在于业务领域+流程引擎,比如:DevOps、RPA、应用与服务编排、数据编排、FaaS编排等。 ------------ ###### 自猿其说Tech-JDL京东物流技术与数据智能部 ###### 作者:马瑞
原创文章,需联系作者,授权转载
上一篇:zookeeper的Leader选举源码解析
下一篇:【敏捷转型,效能提升】敏捷转型实践系列分享(之二)
自猿其说Tech
文章数
426
阅读量
2149963
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2149963
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号