作者:李玉亮

JDEasyFlow是企业金融研发部自研的通用流程编排技术组件,实用于服务编排、工作流、审批流等场景,该组件已开源(https://github.com/JDEasyFlow/jd-easyflow),目前在部门的外部业务零碎和科技输入零碎中广泛应用,其余部门也有应用。

它的特点是简略、灵便、易扩大,开发人员个别30分钟可入门上手,半天可把握其原理。它分为一个外围模块和若干扩大模块,模块之间松耦合,开发应用时可按需抉择、疾速集成、渐进式利用,同时反对JSON内置标准和BPMN标准。它的实现原理也有其特色,前面有介绍。

反对的场景性能

节点流转类型

反对程序流转、条件流转、循环流转等。

节点性能类型

反对脚本节点、用户节点和音讯节点。

脚本节点:节点执行时运行一段代码脚本

用户节点:依据用户的操作指令触发节点执行

音讯节点:接管音讯后触发节点执行

节点串并类型

反对串行执行、并行执行、串并组合执行等。

流程交互场景

反对单次交互一次执行多节点、屡次交互一次执行一节点、屡次交互一次执行多节点等。

子流程场景

JDEasyFlow反对子流程的场景,可将把简单的流程节点拆分为子流程,便于业务逻辑形象。

审批流程场景

JDEasyFlow提供了流程工作审批的能力;罕用的审批、撤销、驳回、会签、加签等性能都可反对;内置了简略的动静表单。既反对从页面发动和操作流程工作,也反对API的形式,京东OA审批零碎也有对接。

性能架构

整体性能架构

JDEasyFlow的性能架构如下图,功能模块之间松耦合, 开发时可按需抉择、疾速集成、渐进式利用最简略的应用形式为只在业务利用端引入jar包应用流程引擎。如果须要流程可视化性能,可集成BPMN标准模块,如果还须要流程实例长久化、流程定义长久化等更丰盛性能,则能够集成其余相干模块。

流程引擎模块

JDEasyFlow的外围模块,此模块提供了基于JSON格局的JDEasyFlow标准进行流程编排的能力,其余模块均基于该模块扩大,相当于流程执行的发动机、CPU。该功能模块为独立组件,无数据库依赖,利用中引入jar包便可应用。

BPMN标准模块

提供了基于BPMN标准进行流程定义和可视化的能力,流程可视化基于[bpmn-js](https://bpmn.io/),其本质为提供了将BPMN格局流程定义转换为JDEasyFlow格局的能力。该模块为独立组件,仅依赖流程引擎模块,无数据库和服务依赖,利用中引入jar包便可应用。

目前可反对罕用的BPMN元素:

工作:脚本工作、用户工作、音讯工作

事件:开始事件、完结事件、音讯接管事件

网关:排他网关、并行网关、容纳网关

流程定义和实例治理模块

流程定义模块反对流程定义的中心化、版本化治理,流程实例模块反对流程实例的长久化和生命周期治理。该性能依赖数据库,有服务端和ERP治理端。

工作/审批模块

反对工作生成、任务分配等性能,罕用的审批、撤销、驳回、会签、加签等性能都可反对。该性能依赖数据库,有服务端和ERP治理端。

零碎架构

整体零碎架构

JDEasyFlow的残缺零碎架构如下,次要有三个端:业务利用端、流程服务端、流程治理端,三个端可部署在单体利用中,也可离开部署。

中间件依赖

· 关系型数据库(如Mysql)

· 缓存(如Redis或R2M)

· 服务通信框架(如Java API调用或Http调用或JSF调用)

数据库数据模型比较简单清晰,见下图:

性能阐明

· 如果仅是服务编排场景,则流程的执行仅依赖内存和CPU,并且是在流程客户端执行,性能上依赖于客户端服务器的性能,一般笔记本实测1秒可执行一个流程申请的1w+个节点,1秒可执行1万+次含1个节点的流程申请

· 如果须要流程状态治理和流程长久化性能,流程引擎在执行时会到流程服务端查问和保留流程实例和流程节点的状态,性能上次要依赖于数据库的查问和插入效率

· 对于流程工作审批性能,流程的工作审批流转是在服务端执行,一方面取决于流程服务端的计算性能,另一方面同样取决于数据库的查问和插入效率

可伸缩性阐明

· 流程引擎属于无状态,可随利用实例线性伸缩

· 流程服务端利用实例反对线性扩大

· 流程数据库可通过分库分表的形式反对大数据量的增长

实际倡议

在具体实际中,倡议部署对立的流程核心(见下图),对流程定义对立治理。各零碎的利用只需集成流程客户端jar包进行流程节点开发和流程调用便可。如果零碎只应用工作审批的性能,则只须要通过API和音讯与流程核心交互便可。

应用示例

流程引擎应用示例

在源码的test目录下有quickstart测试用例(easyflow\easyflow-flow\src\test\java\com\jd\easyflow\flow\quickstart\QuickStartTest.java),可间接运行或调试以理解应用形式和运行原理。具体实际步骤如下:

1、代码中引入easyflow-flow jar包,以maven为例:

<dependency>        <groupId>com.jd.easyflow</groupId>        <artifactId>easyflow-flow</artifactId>        <version>{替换为最新版本}</version></dependency>

2、编写流程定义文件,以node001->node002→node003的执行程序为例:

{"id": "quickstart_001", "name": "Quick Start 001","nodes": [  {"id": "node001","name": "Node001","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart001Node01Action()"},"start": true,"post": {"to": "node002"}},  {"id": "node002","name": "Node002","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart002Node01Action()"},"post": {"to": "node003"}},  {"id": "node003","name": "Node003","action": {"createExp": "new com.jd.easyflow.flow.quickstart.QuickStart003Node01Action()"}}]}

其中QuickStart001Node01Action等为java节点动作类。残缺的流程定义配置项可见: https://github.com/JDEasyFlow/jd-easyflow/wiki/Flow-engine-usage (公网)

3、编写利用启动时加载流程引擎的代码

   FlowEngineImpl flowEngine = new FlowEngineImpl();   flowEngine.setFlowPath("classpath:flow/quickstart/quickstart_001.json");   flowEngine.init();

Spring环境可间接定义FlowEngineImpl bean.

4、编写具体流程调用执行的代码

    FlowParam param = new FlowParam("quickstart_001");    FlowResult result = flowEngine.execute(param);

残缺测试用例的执行后果打印如下:

[main           ] INFO FlowEngineImpl         - Start parsing definition files:easyflow-flow/target/test-classes/flow/quickstart/quickstart_001.json[main           ] INFO FlowEngineImpl         - SART EXECUTE FLOW, flowId:quickstart_001 nodeIds:null[main           ] INFO BaseFlowRunner         - EXECUTE NODE:node001[main           ] INFO QuickStart001Node01Action - Execute Node 001[main           ] INFO BaseFlowRunner         - NEXT NODES:node002[main           ] INFO BaseFlowRunner         - EXECUTE NODE:node002[main           ] INFO QuickStart002Node01Action - Execute Node 002[main           ] INFO BaseFlowRunner         - NEXT NODES:node003[main           ] INFO BaseFlowRunner         - EXECUTE NODE:node003[main           ] INFO QuickStart003Node01Action - Execute Node 003[main           ] INFO BaseFlowRunner         - NEXT NODES:[main           ] INFO QuickStartTest         - Execute finish, current node is:node003

BPMN模块应用示例

关上easyflow-flow-bpmn/BPMNDesigner.html流程设计器. 点击导入按钮,导入easyflow-flow-bpmn/src/test/resources/flow/quickstart/quickstart_001.bpmn文件,可在设计器中看到和以上JSON定义等价的BPMN流程定义.

代码集成应用时只须要将FlowEngineImpl的flowParser设置为BpmnFlowParser.

更多

以上只是流程引擎和BPMN模块的简略应用示例,JDEasyFlow还蕴含其余模块、可反对很多的配置项和应用场景,更多应用可见最初的对接应用介绍.

实现原理

目前市面上的流程编排组件根本都是基于图(边和顶点)构造的,而本组件是参考了计算机指令执行模型而实现,借鉴了程序计数器的实现原理,引擎外部通过相似程序计数器(PC)的待执行节点栈来保护后继节点;能够了解为是一种高级业务编程语言,它同时也是图灵齐备的。

流程引擎外围模型名词只有一个:节点(Node),节点的性能为执行逻辑并输入后续节点 。

开发态可定义无限的节点,通过每个节点与其后续节点连贯造成有向图;运行态按规定逻辑进行节点流转,反对并行执行,反对程序、条件或循环,反对fork-join。

概念:

流程:一个业务流程的形象

节点:流程的组成单位,一个节点可能执行节点动作同时可返回后继节点

节点外部构件:

节点外部构件的组成是可自定义的,流程引擎提供了缺省实现,其外部构件包含了前处理器(PreHandler)、节点动作(NodeAction)、后处理器(PostHandler)

前处理器:判断该节点是否能够执行动作

节点动作:实在的业务性能解决

后处理器:负责计算后续节点

流程引擎执行逻辑

流程引擎有一个或多个流程触发节点,流程触发后执行如下逻辑:

1. 初始化流程上下文

2. 失去流程起始节点ID,放入执行栈

3. 如果执行栈为空,则返回,否则执行以后节点

1) 预查看

2) 执行Action

3) 计算后继节点ID并返回

4. 将后继节点放入执行栈,从栈中取出待执行节点,跳到第3步

因而JDEasyFlow整体的特色为简略

• 模型简略:外围模型概念就是节点的流转

• 扩大简略:提供了监听器、过滤器性能,不便横向切面;节点反对自定义实现

• 定义简略:只须要通过JSON进行节点流转逻辑配置便可,也反对BPMN格局

• 运行简略:代码调用流程引擎,传入流程ID和业务参数便可

• 应用简略:引入组件包便可应用,比拟轻量

实用场景和对接应用阐明

实用场景

实践上JDEasyFlow可满足任何流程场景,它次要可解决三类问题:

流程可编排:将业务流程形象为软件流程,保障软件是事实的实在反映;不同场景可定义不同流程,且流程易批改

性能松耦合:将业务节点形象为软件流程节点,一方面实现性能的松耦合,另一方面实现节点的可复用

流程可视化:所见即所得,不便业务产品人员和软件研发人员基于同一语言的交换,也便于流程监控

在理论软件系统开发过程中,如果有如下诉求,可思考应用流程编排:

• 业务流程是有显著的多个节点组成

• 心愿流程可灵便变更

• 业务流程级别比程序流程高一层,在编程语言级别难以聚合和治理(如一个流程即须要前台操作,又有外零碎参加,又有后盾操作,在实现上入口扩散)

对接应用

JDEasyFlow的所有文档可见: https://github.com/JDEasyFlow/jd-easyflow/wiki (公网)

欢送大家对接应用,有相干应用问题可分割: liyuliang5@jd.com