通用流程编排引擎介绍-程序员宅基地

技术标签: java  git  前端  

介绍

什么是流程编排引擎

刚开始学习编程的时候,就梦想要是有一天,我们可以通过拖拽的方式来开发软件该多爽。当我第一次接触到流程编排引擎时,真有点梦想照进现实的感觉。流程编排简单来说,就是通过拖拽可视化业务组件来编排业务流程,然后由流程引擎来执行这个流程。通过这种方式来提高业务软件的开发和运维效率。

本文主要介绍通用流程编排引擎的历史和它的使用方式,帮助大家来了解流程编排。之后再粗略介绍下我之前参与开发的一套通用流程编排引擎的实现,供大家参考。

为什么要用流程编排引擎

从业务角度来看

  • 首先,业务人员无法感知散落在系统代码中的流程逻辑,不能评判流程实现是否满足业务需求。
  • 其次,轻微的流程变动都需要开发去修改代码,重新发布走完整个迭代流程,无法快速支持业务变化。

从技术角度来看

  • 一方面,流程很多,单纯依靠代码来维护流程很快就会演变成代码灾难。
  • 另一方面,流程经常变化,修改流程代码的影响面难以评估,导致业务上一个很小的变更都需要很小心的去修改代码,还要去覆盖测试很多无关流程的代码。

举个简单的例子

比如在物流领域,一件商品从揽件,入库,出库,调仓,运送,配送会经过很多流程节点;不同的商品流转的过程又不一样,比如家电配送可能从厂商核心仓出库,配送,不需要入库操作,干线运输和终端配送的物流公司可能不同,需要判断是否做干配分离等等

家电配送流程图

小商品配送,比如衣服等需要先从商家揽件,然后入库,安排运配车辆,再运输配送。这里面还涉及到揽件超时的处理,以及出库后直接配送还是要调换仓库等逻辑判断。

小商品配送流程图

这么多流程,如果全都靠代码来维护,那么系统规模很快就会超出人能够理解的范围,对任何一个团队都会是灾难。再一个流程会经常变化,相同商品,不同时间段的流程也不一样,比如同样一件商品,在大促的时候,可能运力比较缺乏,那么就要在运送之前,加上一个Hold单的操作,防止把下游的仓库或者运力压垮。

这里面,不变的是流程上面各个节点的操作,比如入库,都是扫商品二维码,然后填充必要信息,然后进行货品入库操作。变化的是流程。流程编排引擎的目的,就是把不变的这些操作抽象成流程节点,变化的流程用可视化的方式去编排。这样我们就有机会复用每个节点的能力,同时快速灵活的去应对流程变化。

当然流程编排不仅仅在物流领域起作用,其他典型的用户,比如视频网站,他们用编排引擎来实现视频的上传,审核,发布,撤回的流程;测试团队依赖编排引擎来做测试流程的编排等等。

BPMN协议

BPMN协议是流程编排引擎领域的标准协议,它奠定了流程编排引擎开发实现的基础。

BPMN协议介绍

BPMN规范业务流程模型注解(Business Process Modeling Notation - BPMN),是一套通用的业务流程建模符号,和传统的流程图的区别如下:

  • BPMN是一个正式的规范,各种图标、元件是有准确的含义和使用规范
  • BPMN可以描述基于事件触发的行为,比如响应超时、外部系统无法提供服务等

2004年BPMI发布了第一版BPMN协议,定义了流程编排的基础模型。2007年,BPMN2.0发布,在1.x基础上新增了存储、交互、执行等规范。下图是BPMN协议基础模型的总结

BPMN协议的实现

目前业界主流的流程编排引擎主要有:JBPM,activiti

JBPM(Java Business Process Management)

JBPM 是JBOSS 公司的产品,它出现的时候,标准协议还是BPMN 1.x,接口比较杂,接入成本高。JBPM 5 是在JBPM 4 和 Drools 合并后,从Drools Flow重新开始做的一个产品,支持BPMN 2.0协议和规则引擎协议DMN,目前最高版本JPBM7。

Activiti

Alfresco软件开发,基于JBPM4,是JBPM创建人离开JBPM后建立的项目,后并入OMG,目前最高版本activiti 7。activiti6的开发团队在新版本中去除了PVM,纳入了DMN,重构XML解析,BUG较多,目前主要团队致力于activiti7,5&6已经不维护。

activiti

JBPM 5

可视化

支持

支持

开源

支持协议

BPMN2.0, DMN

BPMN2.0, DMN

流程格式

bpmn2.0, xPDL

bpmn2.0

持久层

Mybattis

Hibernate

执行引擎

PVM

Drools

技术前身

JBPM 4

JBPM4 + Drools

DMN或Decision Modeling Notation(决策建模符号)是用于业务决策的图形语言。DMN的主要目的是为分析人员提供一种工具,用于将业务决策逻辑与业务流程分离,这有助于大大降低业务流程模型的复杂性并促进其可读性,使用DMN封装业务决策逻辑还允许业务流程或业务规则在不相互影响的情况下进行更改。

流程虚拟机 (Process Virtual Machine - PVM)通用功能 (持久化,事务,配置,也有基本流程结构,等等)

了解流程编排相关概念,再来看下如何使用流程编排引擎。

使用

我们从一个简单的用户登陆流程来说明如何去使用流程编排引擎。

定义流程

给流程起名字,这里就叫做 UserLoginExampleProcess。考虑到易用性,可以提供流程复制的功能,从已有的流程中复制一份来定义新流程。

画流程图

提供个用户一个流程编辑页面。用户通过拖拽组件来拼接出业务流程。常用的组件可以分为3类。

  • 任务组件

  • 网关组件

  • 事件组件

除了配置节点之外,流程图本身也可以配置流程全局的扩展属性,比如用户登陆流程中,可以配置一个全局属性叫:userId, 这样整个流程的各个节点都可以取到这个值。程序执行流程时,可以通过setProperties来填充userId。

配置任务

任务节点是真正执行服务的节点。任务又可以分为人工任务和服务任务。

  • 人工任务:顾名思义就是需要人去参与执行的任务节点,比如审批节点,需要发消息给某个人去执行审批动作。

  • 服务任务:节点绑定某个服务。这里的服务可以是http接口,java接口,也可以是hsf,double之类的微服务。服务类型是可以扩展的,BPMN 2.0本身只提供协议,不限制服务的类型,各个引擎可以自己提供实现。比如用户登陆流程中的:检验用户信息就是一个任务节点。流程引擎执行到这个节点时,会去调用这个节点上面配置的服务接口。这个服务的入参,可以从上一个节点获取,也可以从整个流程级别的参数获取。服务的出参会保存在节点的执行结果中,供后续节点使用。

配置网关

网关类似于代码中的if-else,用来做业务逻辑控制。网关的类型又分为

  • 排他网关:网关的多条出度线中只能有一条符合条件

  • 并行网关:网关的出度线中有多条服务条件,可以并行执行

此外还有聚合网关事件网关等不同类型。同样网关的类型也支持扩展,BPMN 2.0协议定义了网关的基本行为,即根据输入决定流程分支。具体的实现由引擎去决定的。

配置事件

事件节点,顾名思义就是由这些节点去控制流程执行的启动,等待和终止。最常见的就是开始事件结束事件。比如用户登陆流程中的启动和结束节点。

除了这两种基本事件之外,还有定时边界事件。这个事件是配置在任务节点上的,比如任务节点调用一个hsf接口一直没有返回,那么为了防止流程卡死,需要在任务节点上配置定时事件:任务执行n秒之后超时,执行定时边界事件决定的流程路径。

此外还有消息等待事件。当流程执行到消息等待事件节点后,会暂停运行,等到接收到外界的异步消息后才重新启动继续执行。和网关、任务节点一样,事件节点同样可以根据引擎实现的需要来扩展和定制。

参数传递

事件每一个节点的执行,依赖于之前节点的输出,或者流程的静态参数。这些参数由节点前面的入度线配置。参数值通过QL表达式从流程执行上下文提取。

流程执行

流程编排引擎客户端从服务器拉取流程定义(通常是xml文件)转换成POJO对象,通过流程名字和版本号等流程信息来启动流程。伪代码如下

//指定流程名称,版本号以及流程参数

ExecuteResult result = Runtime.startProcess(StartProcessContext.builder()

.processName("UserLoginExampleProcess")

.version(1)

.processParams(new HashMap<>()).build());

以上是流程编排引擎的用法。接下来介绍流程编排引擎的开发实现。

实现

既然已经有了通用开源的流程编排引擎,为何还要自己开发呢?这里主要考虑不同公司的业务适配性。activiti是通用的流程编排引擎,但是它太通用了,不一定符合公司的需求。比如

  • activiti支持用户任务,用户任务要选人,涉及到每个公司自己的账号体系,如何去适配呢?
  • activiti会把流程执行时每个节点的数据保存下来,那如果我想要无状态的流程执行,不需要保存数据,怎么办呢?

这些需求都要求深入的修改activiti的代码逻辑。好在activiti是开源的,参照它的源码迭代出一套服务自己的公司业务的编排引擎,成本还是可以接受的。

架构

完整的流程编排,需要提供流程编辑页面,流程执行的二方包,以及流程管理的后端服务。大体上可以划分为一下几块

前端

前端提供个用户定义流程,编排流程的基础能力。除此之外,需要有流程的

  1. 流程编辑能力,要提供可视化的流程编辑器
  2. 版本管理能力,支持流程的版本迭代
  3. 流程调试能力,可视化的调试流程,方便编排
  4. 流程执行记录查看和管理的能力

流程编排能力需要考虑有些业务方有自己的管理页面,需要在自己的页面中嵌入流程编排能力。这时候需要提供一套通用的流程组件库,并允许用户自定义组件样式和部分行为。

服务端

服务端主要分为3个模块

  1. 租户管理:通用流程编排面向不同的业务方,业务方直接要做业务隔离。因此需要提供多租户管理的能力
  2. 流程管理:流程增删改查的功能,外加流程版本管理等能力
  3. 流程实例管理:流程执行完产生流程实例数据,保存到数据库供用户查看。考虑不同租户数据量级不同,为了隔离租户数据,服务端可以提供数据存储的抽象层,允许用户自己实现数据存储逻辑,自己管理存储数据,防止高频租户的数据影响其他租户的性能。

除了这3个模块之外,服务端还要考虑可能的扩展。比如人工任务节点,需要支持选人的能力,要支持不同的业务方可能用的不同的用户体系;比如定时边界事件,需要依赖定时调度系统,需要能够方便的切换依赖。

客户端

客户端的核心是流程编排的执行引擎。业务方通常依赖流程编排引擎提供的二方包来执行流程。二方包需要提供:

  1. 流程拉取,从服务端拉取xml流程定义,并转成POJO对象缓存起来,方便执行,降低网络耗时
  2. 流程执行,运行流程实例,执行每个流程定义的节点任务
  3. 实例保存,保存流程执行产生的流程实例
  4. 流程重跑,流程实例允许失败,需要从某个节点重新触发。除此之外还要提供暂停,终止等功能
  5. 流程debug,前端提供的debug能力,需要有具体的客户端去负责执行
  6. 本地灾备,考虑服务端失效的可能,把业务方关心的流程定义保存在本地磁盘,或者公共磁盘,防止运行时找不到流程。

BPMN 2.0 协议不仅仅定义了流程元数据,也定义了流程的交换,存储和执行。通用流程编排引擎的实现主要分两个部分,一是流程元数据的定义,二是流程执行引擎的实现。

元数据实现

流程执行引擎实现

执行引擎的核心在于解析流程图,按顺序执行流程定义中的节点。执行引擎的实现逻辑也不复杂,搞懂两个常见的设计模式,也就搞懂执行引擎了。

命令模式和责任链模式

命令模式:把请求封装成命令对象,请求者通过命令来控制执行者。从而实现请求和执行的解耦。执行引擎通过把流程的启动,执行,暂停,终止等请求封装成命令对象,方便使用者去控制流程执行。

责任链模式:一个流程的处理需要解析流程图,记录日志,流程执行,结果保存等步骤。这些步骤通过责任链串联起来,向调用者屏蔽各个步骤的执行过程。降低流程执行的复杂度。执行过程如下

整个责任链的核心是InvokeInterceptor, 它把流程对象加载到内存,解析出流程中的节点元素一个个去遍历执行。这里的遍历,不是简单的把所有的节点元素塞进队列然后一个个读取。而是用类似懒加载的模式,维护一个先进先出的元素队列,每次处理队列中的第一个元素:

  1. 执行元素绑定的动作,比如任务节点,调用它绑定的java接口,网关执行它的业务判断逻辑等

  2. 识别该元素的下一个元素,放入待处理的元素队列中

  3. 递归第一步,直到队列为空或者被暂停

通过递归队列的方式,可以实现流程的正确执行,并且避免了冗余节点的加载。当然也要考虑潜在的问题,比如难以识别流程中的死循环等等。

总体而言,通用流程编排对于强流程业务,比如请求审批,物流编排等业务来说,能够极大减少流程代码的开发和维护,显著提高项目开发效率。另一方面对于没接触过流程编排的开发同学来说,从零开始开发编排引擎的成本较高。好在有activiti, JPMN这些开源项目珠玉在前,学习开源代码,开发一套适配本公司业务的流程引擎,性价比还是蛮高的,值得大家去尝试。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/changtianshuiyue/article/details/125740091

智能推荐

【史上最易懂】马尔科夫链-蒙特卡洛方法:基于马尔科夫链的采样方法,从概率分布中随机抽取样本,从而得到分布的近似_马尔科夫链期望怎么求-程序员宅基地

文章浏览阅读1.3k次,点赞40次,收藏19次。虽然你不能直接计算每个房间的人数,但通过马尔科夫链的蒙特卡洛方法,你可以从任意状态(房间)开始采样,并最终收敛到目标分布(人数分布)。然后,根据一个规则(假设转移概率是基于房间的人数,人数较多的房间具有较高的转移概率),你随机选择一个相邻的房间作为下一个状态。比如在巨大城堡,里面有很多房间,找到每个房间里的人数分布情况(每个房间被访问的次数),但是你不能一次进入所有的房间并计数。但是,当你重复这个过程很多次时,你会发现你更有可能停留在人数更多的房间,而在人数较少的房间停留的次数较少。_马尔科夫链期望怎么求

linux以root登陆命令,su命令和sudo命令,以及限制root用户登录-程序员宅基地

文章浏览阅读3.9k次。一、su命令su命令用于切换当前用户身份到其他用户身份,变更时须输入所要变更的用户帐号与密码。命令su的格式为:su [-] username1、后面可以跟 ‘-‘ 也可以不跟,普通用户su不加username时就是切换到root用户,当然root用户同样可以su到普通用户。 ‘-‘ 这个字符的作用是,加上后会初始化当前用户的各种环境变量。下面看下加‘-’和不加‘-’的区别:root用户切换到普通..._限制su root登陆

精通VC与Matlab联合编程(六)_精通vc和matlab联合编程 六-程序员宅基地

文章浏览阅读1.2k次。精通VC与Matlab联合编程(六)作者:邓科下载源代码浅析VC与MATLAB联合编程浅析VC与MATLAB联合编程浅析VC与MATLAB联合编程浅析VC与MATLAB联合编程浅析VC与MATLAB联合编程  Matlab C/C++函数库是Matlab扩展功能重要的组成部分,包含了大量的用C/C++语言重新编写的Matlab函数,主要包括初等数学函数、线形代数函数、矩阵操作函数、数值计算函数_精通vc和matlab联合编程 六

Asp.Net MVC2中扩展ModelMetadata的DescriptionAttribute。-程序员宅基地

文章浏览阅读128次。在MVC2中默认并没有实现DescriptionAttribute(虽然可以找到这个属性,通过阅读MVC源码,发现并没有实现方法),这很不方便,特别是我们使用EditorForModel的时候,我们需要对字段进行简要的介绍,下面来扩展这个属性。新建类 DescriptionMetadataProvider然后重写DataAnnotationsModelMetadataPro..._asp.net mvc 模型description

领域模型架构 eShopOnWeb项目分析 上-程序员宅基地

文章浏览阅读1.3k次。一.概述  本篇继续探讨web应用架构,讲基于DDD风格下最初的领域模型架构,不同于DDD风格下CQRS架构,二者架构主要区别是领域层的变化。 架构的演变是从领域模型到C..._eshoponweb

Springboot中使用kafka_springboot kafka-程序员宅基地

文章浏览阅读2.6w次,点赞23次,收藏85次。首先说明,本人之前没用过zookeeper、kafka等,尚硅谷十几个小时的教程实在没有耐心看,现在我也不知道分区、副本之类的概念。用kafka只是听说他比RabbitMQ快,我也是昨天晚上刚使用,下文中若有讲错的地方或者我的理解与它的本质有偏差的地方请包涵。此文背景的环境是windows,linux流程也差不多。 官网下载kafka,选择Binary downloads Apache Kafka 解压在D盘下或者什么地方,注意不要放在桌面等绝对路径太长的地方 打开conf_springboot kafka

随便推点

VS2008+水晶报表 发布后可能无法打印的解决办法_水晶报表 不能打印-程序员宅基地

文章浏览阅读1k次。编好水晶报表代码,用的是ActiveX模式,在本机运行,第一次运行提示安装ActiveX控件,安装后,一切正常,能正常打印,但发布到网站那边运行,可能是一闪而过,连提示安装ActiveX控件也没有,甚至相关的功能图标都不能正常显示,再点"打印图标"也是没反应解决方法是: 1.先下载"PrintControl.cab" http://support.businessobjects.c_水晶报表 不能打印

一. UC/OS-Ⅱ简介_ucos-程序员宅基地

文章浏览阅读1.3k次。绝大部分UC/OS-II的源码是用移植性很强的ANSI C写的。也就是说某产品可以只使用很少几个UC/OS-II调用,而另一个产品则使用了几乎所有UC/OS-II的功能,这样可以减少产品中的UC/OS-II所需的存储器空间(RAM和ROM)。UC/OS-II是为嵌入式应用而设计的,这就意味着,只要用户有固化手段(C编译、连接、下载和固化), UC/OS-II可以嵌入到用户的产品中成为产品的一部分。1998年uC/OS-II,目前的版本uC/OS -II V2.61,2.72。1.UC/OS-Ⅱ简介。_ucos

python自动化运维要学什么,python自动化运维项目_运维学python该学些什么-程序员宅基地

文章浏览阅读614次,点赞22次,收藏11次。大家好,本文将围绕python自动化运维需要掌握的技能展开说明,python自动化运维从入门到精通是一个很多人都想弄明白的事情,想搞清楚python自动化运维快速入门 pdf需要先了解以下几个事情。这篇文章主要介绍了一个有趣的事情,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。_运维学python该学些什么

解决IISASP调用XmlHTTP出现msxml3.dll (0x80070005) 拒绝访问的错误-程序员宅基地

文章浏览阅读524次。2019独角兽企业重金招聘Python工程师标准>>> ..._hotfix for msxml 4.0 service pack 2 - kb832414

python和易语言的脚本哪门更实用?_易语言还是python适合辅助-程序员宅基地

文章浏览阅读546次。python和易语言的脚本哪门更实用?_易语言还是python适合辅助

redis watch使用场景_详解redis中的锁以及使用场景-程序员宅基地

文章浏览阅读134次。详解redis中的锁以及使用场景,指令,事务,分布式,命令,时间详解redis中的锁以及使用场景易采站长站,站长之家为您整理了详解redis中的锁以及使用场景的相关内容。分布式锁什么是分布式锁?分布式锁是控制分布式系统之间同步访问共享资源的一种方式。为什么要使用分布式锁?​ 为了保证共享资源的数据一致性。什么场景下使用分布式锁?​ 数据重要且要保证一致性如何实现分布式锁?主要介绍使用redis来实..._redis setnx watch

推荐文章

热门文章

相关标签