1. 引言
由于Activiti面世出现也比较早,加上是Java领域的开源工作流,自然而然也被很多企业个人拿来使用,有做做简单的或有深入的二次开发使用的。作为一个资深的BPM领域技术专家,貌似如果没有研究过Activiti的话会显得不专业,所以我们也免不了俗,自然而然也是对Activiti做过剖析。
关于Activiti的选型还是有必要说一说,从纯技术角度上说,不从所谓商业角度,因为那不是讨论的范畴。所以正好以此为契机把它整理成一篇全面一些的文章,就想着也提供给有需要的技术达人在Activiti选型时的参考。Activiti本身有很多优秀的地方,但也有很多弊端,谈论过程中如果您有不同的观点我们也是很欢迎接受的,我们也是从某个角度谈谈聊聊,仅作参考。
2. 什么是Activiti
Activiti是Tom Bayen(jBPM创始人)自2010年离开jBoss加入Alfresco公司后的又一力作:第一版在2010年5月发布,当时仅支持最简单的流程处理,之后的版本陆续完善了对BPMN 2.0规范的支持。其核心是使用Java开发的。其前就是JBPM。
早年关于研发工作流的厂商也少,而Activiti开源早,所以占领的知名度的先机,但目前国内自主研发的流程引擎也越来越多,而且更加符合中国国情的项目,甚至远远越过了Activiti。易用易上手。容易扩展,即拿即用。
2.1. Activiti核心数据库表
Activiti的后台是有数据库的支持,所有的表都以ACT_开头。
ACT_RE_*: ‘RE’表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
ACT_RU_*: ‘RU’表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
ACT_ID_*: ‘ID’表示identity。 这些表包含身份信息,比如用户,组等等。
ACT_HI_*: ‘HI’表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
ACT_GE_*: 通用数据, 用于不同场景下,如存放资源文件。
3. Activiti优点
1、 最大的优点就是免费开源,这也是很多人选择的原因
2、 小项目中应用简单的串行并行流转基本能满足需求。
4. Activiti存在问题
4.1. 节点定义概念不同
节点理解不同:在Activiti中将节点理解为脚本任务,用户任务等,这样表达有点让人容易产生理解偏差,通常在我们的理解里如果是一个任务那么任务就是一件具体的事情,比如让一个人去挑水,就是一件很具体不可再细分的事情,所以叫把节点叫用户任务是不太准确,因为节点来说必然是可再细分的对象,有可能多个人处理,或者其它可再分的情况。
在微软的WF工作流中把节点叫作“活动”Activity(活动),我认为是比较好的,因为一个节点就是一个集体活动的事情,一个流程是由一个个集体事务(活动)组成一个流程,流程是最大集体事务,分解成一个个节点活动,那么活动是由人员参与进来的,多个人参与一个活动共同完成这个活动。
这里谈的其实涉及到表达的问题,其实都是一些看法和思考,采用什么“粒度划分”,采用哪个名词表示从中国式的流程来看,个人认为将节点使用“活动”来表达表示可再分,任务仅仅就表示一个任务已经是最细颗粒度不可再分为更好,更易理解。
思想定了就会影响设计,通常在设计代码写法上也会把这种表达用来命名。
4.2. 缺乏详细的节点实例和任务实例关系轨迹,缺乏可“追溯”性
缺少节点实例轨迹数据的持久化,Activiti运行时紧紧围绕act_ru_execution这张表来工作,此表也是整个流程引擎的运行核心表,执行时是一个树型表,这张表就是节点运行实例的过程,而且使用PARENT_ID_来从一个节点到多个节点的过程,只是仅仅有一个Parent_Id_来维护是不够的,因为我们知道关系有可能这是样的正向生成的树,也有倒生长的树:
如上图:E到F,G 是正向成长的,而F,G到H是倒挂的树,虽然上图有点简单,但意思也能表达到,就是正向树与倒向树时,仅有一个ParentId是不能满足的,当Activiti倒向树时这个表的数据相对会复杂很多,对于这情况情如果你不能很精深理解Activiti或者因二次开发功能上的需求强制使用代码来修改这张表,那么将会埋下不少的“坑”,给将来程序留下不少隐患。Activiti对于这表的执行过后会进行删除数据,节点完成一个就会删除一条数据,也就是节点实例数据并不持久保存, 执行完就删除掉还节点数据库容易,其实这样问题又来了,驳回怎么办,这也是Activti对驳回的支持很弱的原因,几乎也在告诉你不好意思,我们国外没有驳回的概念。通常办法就是在节点上做事件切面然后记录下来,但往往记录的也只能是节点定义Id之关的过程,并没有实例紧密性的关系层次记录。
二次开发住住因业务要求,中国式的流程审批的要求,对此表的修改估计是很多基于Activti为基础开发的工作流必不可少的事情,如果是正向树通过删除或修改数据来改变流程的流转相对危险没有那么高,如果是一个倒挂树的模型时,那将会很麻烦,同时不可预见性的概率将增大。
比如下图模型。
同时Activiti缺少任务实例轨迹(此任务并不是Activiti对节点叫任务的表达),因为业务过程往往需要有追溯,工作流的好处正因为有流程的理念并有“追溯”明确落到到人的责任痕迹,所以精确清晰的“追溯”是必不可少的,需要知道A任务是由哪个任务传递过来的,知道从哪里来然后又去了哪里,哪些人参与了,发生了什么事情。
缺乏详细的轨迹也是导致Activiti先天关于驳回功能的脆弱性,当然强制扩展轨迹记录也是做得到,只是所记录的也并不是完全正确。Ativiti的执行过程是必须依懒流程图的,如果图上没有画线是不能执行的。
4.3. 扩展需要与很多的Event来实现
Activiti需要经过大量的扩展才能应用起来,直接从官网下载下来的Activiti要达到企业级应用还需要一段痛苦的改造之路要走。Activti的扩展非常依懒事件监听和AOP切面事件,其中一个常用的扩展之一就是在执行过程修改Activiti的源代码,然后在网关节点的代码中广播各种事件通过SpringMVC来捕获这些事件,交给事件来进行流程执行过程中的数据进行记录,从而达到扩展的目的,从表面上来看似乎问题不大,但从日积月累后你会发现,整个执行过程就像一个GOTO语法,代码执行到路乱跳,非常的不好维护,可读性也差,一是维护人员的技术门槛非常高,二是越到后面代码越难维护。久而久之会把项目拖跨。
4.4. 二次开发难度大,门槛高
要真正把Activti用好的话,其实还需要做大量的开发封装,首先得对Activiti有进行学习研究,理解透了才能进行改造。
Activti最明显的一个地方就是事件机制,简单来说把Activti执行过程理解为一条直线,这条执行直线上你要做很多的AOP拦截,对这个拦截进行事件抛出,然后自己再捕获这个事件进行扩展开发。如下图:正如下图所示,AOP是非常好的设计思想,只是其实一个核心逻辑通过大量的AOP来扩展后达到核心运行逻辑这势必数据容易导致混乱和数据的脆弱性,使用过度事件广播来达到改造的目的,而且事件之间还存在相关联。
5. 总结
Activti的学习价值比较高,是工作流入门的好教材,可以学习里面好的代码风格和思路。但是要拿Activiti做到中国式的企业级应用门槛和难度很高。想用Activiti来做企业应用,还需要经地大量的改造,本文提到的缺点仅仅也只是一部份,实际中碰到的问题将更多。
6. 推荐学习资料
自行百度搜索WFMC工作流标准联盟的相关文档
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/7603.html