Redian新闻
>
流程引擎的架构设计

流程引擎的架构设计

公众号新闻

来源 | OSCHINA 社区

作者 | 京东云开发者-马瑞

原文链接:https://my.oschina.net/u/4090830/blog/5584471

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 编排等。

作者:马瑞


END






这里有最新开源资讯、软件更新、技术干货等内容
点这里 ↓↓↓ 记得 关注✔ 标星⭐ 哦~

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
APISIX 在君润人力云原生平台的架构实践架构师应该遵守的设计原则如何在面试中巧妙展现架构能力?附200道面试真题+100例经典架构案例拆解 | 极客时间外交部:奉劝少数西方国家放下教师爷的架子如果面试官让你设计美团外卖的分库分表架构,就该这么说!秋阳杲杲科技周报:俞敏洪罗永浩入驻淘宝直播;李宁回应新品设计争议;消息称小鹏汽车调整组织架构0-2岁产品新人:原型设计没思路,这4大标准流程你知道吗?纽维:因为本田引擎找回了设计动力全新设计,来自德国IF红点设计获奖设计团队倾心之作:全触大屏通话智能手表超融合架构与云、传统架构对比教育随笔(108)高考文言文备考之九【绿色金融】《金融机构科学净零目标设定》基础性文件—SBTi | 金融机构设立科学碳目标:从承诺到行动芯片架构设计的新趋势周末愉快 冬瓜Arm急了?高通爆料ARM架构SoC将不允许外部GPU等设计,三星联发科等芯片厂商“被连坐”最新统计!13省市发布体育类校外培训机构设置标准、办学面积,审批流程新上任的财务总监,对财务部组织结构设计的调整元宇宙创新者3:渲光引擎的缘起、沉浮与新生前完美世界副总裁崔铭:从游戏引擎到商业引擎|36氪专访总结如何画一手好的架构图趣图:公司来了一个牛逼的架构师GitHub 前 CTO:全面微服务是最大的架构错误!网友:这不是刚改完吗...计算机架构设计的 8 个伟大思想AMD最强RDNA 3架构GPU发布,小芯片设计、支持DP2.1接口,899美元起埃及艳后Kleopatra如何成为一名优秀的架构师 | ArchSummit支付设计白皮书:支付系统的总架构广东发布科技类校外培训机构设置标准毫末智行社招:高精地图引擎工程师、泊车-SLAM算法专家、系统架构师、产品经理等架构设计:为什么说复用是邪恶的?中央美术学院设计学院创新设计教研室主任程书馨:“创新几何”作为创新设计的一个基本框架Tair 对 Redis 引擎架构之争的看法Most Beautiful Duets Ever(四)支撑千亿级日交易额,平安科技分布式数据库架构设计
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。