UML软件工程组织

 

 

微内核过程引擎的设计思路和构架
 
作者:胡长城 来源:.csdn.
 

这两年基于流程引擎技术构建的应用系统越来越受到客户的追捧和认可,能否支持 “流程可定制、可更改、可运行”也逐渐成为客户衡量一个应用系统主要标准之一。又比如目前被大家广泛提及的SOA(面向服务架构),为客户解决“业务敏捷性问题”提供了新的指导思想和方法。但是SOA的整体构架必须依赖于三方面技术的支撑:解决互通互联的技术与标准,比如我们所熟知的消息总线技术、JBI、SCA等等;解决流程管理的技术与标准,比如BPM,Workflow等;以及解决业务模型构建的技术与标准,正如我们所熟知的MDA(模型驱动架构)等。可见与流程应用相关技术的重要性。

最近也有很多企业的朋友向我抱怨他们给客户实施工作流项目的时候,不论是采用第三方的工作流产品,还是扩展开发开源的工作流引擎,总是非常棘手,碰到很多难以应对的问题,而且这些问题一般出现在项目后期。因为在需求调研的过程中客户也无法欲知,因为客户也不清楚流程系统应该具有什么功能。

可以说,从工作流项目实施角度可以阐述很多可以注意的事项,但是本篇从另一个角度来辅助大家看待流程问题。这个角度完全是从一个“源”角度来探索—— 如果你清楚了一个过程引擎的实现思路和构架,我想你就不会在为那“怪异的客户需求”而惊奇了,相反,你可以很轻松的应对。

是的,本篇主旨就是讲解“微内核过程引擎的设计思路和构架”。

在进入文章正文之前,我还有必要稍稍补充两点:

(1)在前一篇杨洪波先生已经为大家诠释了工作流(Workflow)与业务流程管理(BPM)的异同。为了减少名词概念方面的误导性,本篇采用了流程(Process)这个概念,来规避Workflow与Business Process所可能带来的概念差异性。当然,不论是工作流还是BPM,解决的根本问题都是流程(Process)问题。

(2)过程引擎的实现技术已经超越了单纯的技术语言、技术模式、构架。在阅读本篇之后(或之前),如果您对工作流引擎的实现感兴趣,那么尽可能的把工作流基本概念、模型、建模方法、系统参考模型等方面的内容浏览一下,可能更有助于您阅读本篇。

当我们试图去实施一个工作流项目,或者研发一个过程引擎的时候,我们将面临很多的问题需要解决:流程有分支,有聚合;客户又要会签,还要回退;组织模型需要适配,权限要控制到数据;等等诸如此类的问题。

正如上面这张图所示,可能单个问题比较容易解决,但是这么多需要考虑的地方融汇在一起,就演变成一个非常复杂的问题了。

但是,再复杂的问题也都可以通过逐步分解、剥离,分步、分层的进行构建,从而逐步解决。本文的主旨就是通过提供一套设计流程的思路和引擎构架来辅助大家解决这个问题。限于文章篇幅,很多地方本文只能“点到即止”,如果对过程引擎构建干兴趣的化,那么在阅读本篇之后,还需要花费较多的时间巩固相关知识才可。

在工作流大师Aalst的《工作流管理:模型、方法和系统》一书中,为理解工作流划定了一个参考框架(Reference Framwork)。这个参考框架包含三部分:基本概念;过程建模和分析;描述工作流管理系统的功能和体系结构。

当我们试图设计过程引擎的时候,需要牢牢围绕这三个层面展开:掌握了基本概念才能真正理解什么流程;懂得了过程建模才能知道如何去描述流程;理解了工作流系统结构才能着手设计过程引擎。

流程设计原则(思路)一:过程建模

可能有人说,“描述一个流程”根本不是问题啊,那个工作流管理联盟(WfMC)组织所定义的XPDL不正是“基于XML的过程描述语言”吗。的确是这样的,WfMC通过一个XPDL语言告诉人们改如何去描述一个流程,或者用官方的语言说,XPDL是工作流参考模型中接口1的实现。

但当你在抠XPDL那复杂的Schema的时候,你是否已经注意到了WfMC所阐述的Workflow Definition Meta Model呢?可能很多人并没有注意到这一点。WfMC早在1995年发布《工作流参考模型(Workflow Reference Model)》这份文档的时候,就已经阐述了这个过程定义元模型。

但是,WfMC所阐述的过程定义元模型并不是唯一的,也就是说,存在很多流程产品采用的并不是这套描述语言。这样的差异性是由于“过程建模方法”的不同所引起的。目前在流程领域主要存在如下的建模方法:Petri网模型,有限状态机(FSM)模型,活动图模型,以及事件过程驱动链(EPC)模型,当然,我们所知道的WfMC的过程定义元模型估计也可以算上吧。比如我们所熟支持的开源引擎JBoss jBPM就是采用的活动图模型。

限于主题与篇幅问题,不在这里阐述过程建模方法的相关知识。

任何流程都是由两个最基本的元素组成:“节点”及“有向连接”。对于“有向连接”几乎没有任何歧义,所有的流程建模描述中“有向连接”都是存在“From”和“To”这两个特性。但是对于“节点”,则因为所处的视角、功能不同,则存在很多不同的理解了。

比如WfMC的过程定义元模型,它所阐述的“节点”就是“活动(Activity)”,但是这活动有很多实现类型:有人工的、有自动的,有子流程的,等等。

比如jBpm这个引擎所依赖的活动图,它所阐述的“节点”是两种:一种是表示真正业务意义上的节点,叫做State;而另一种是表示逻辑连接(Logic Connector)的节点。

再比如EPC这个建模方法,它所阐述的“节点”则是三种:一种是表示某种状态发生的节点,叫做Event;另一种是表示真正业务功能的,叫做Fuction;第三种则是表示逻辑连接(Logic Connector)的节点。但是,EPC的逻辑连接节点和jBpm的逻辑连接节点的含义、种类又有所不同。

上面的例子,则说明了我们可以用很多种方式来“描述流程”。当你试图去研发流程系统的时候,寻找一套最适合自己的“描述流程”的方式,则是首当其冲。

越过这道坎的难度是很大的,因为很多技术人员对工作流的基本概念和建模方法理解不多。好在WfMC的XPDL还是很完备的,为我们提供了一个很详细的参考实现。而且国际、国内上很多著名的工作流产品,其过程定义就是遵循XPDL规范的。

流程设计原则(思路)二:过程定义与实例的关系

如果这时候确定了过程定义的模型,那么接下来最重要的就是考虑过程定义与过程实例的关系了。这可不是“类”与“对象实例”那样简单的关系了。

在WfMC的规范中,阐述了过程定义与过程实例之间一种简易的关系,如下图所示:

      

这种关系是非常简单的表述,但现实中的应用远比这更为复杂。在同一个流程实例(Process Instance)中,一个活动节点(Activity)就只存在一个活动实例(Activity Instance)吗?在现实应用中,存在非常复杂的多实例情形出现,比如因为某种原因造成“回退”之后再返回,可能同一个活动节点就会被执行两次甚至多次;再比如,因为某一个节点多个处理人的异步执行,则也有可能引发后续节点被重复执行的情况。

这种定于与实例的支持关系需要在设计流程引擎之前就考虑情况,否则在后续面对客户应用的时候,就可能存在措手不及的情况。

以上仅仅讲了两个基本的设计思路,面对设计任何流程引擎或者扩展开发现有的引擎的时候,都需要缕清楚这两方面的思路和设计特点。当然对于整个引擎的设计,还有其他很多方面需要考虑,比如流程调度、所依赖的状态、所引起的事件等等。限于文章篇幅,不在这里阐述。

设计思路之三:微内核

微内核(micro kernel)这个概念最早是由Richard Rashid提出的,虽然这个最初是为了构建基于消息传送机制的微内核操作系统,并不是为了软件构架服务的。但是,最近几年,随着“构件化”“分层”软件体制的发展,微内核技术和构建思想逐渐被引入到软件设计构架中,用于“尽可能的解耦组件之间的关系”。

与微内核设计理念相对应的则是宏内核(monolithic kernel),这也是一个源自操作系统级别的概念。对于宏内核来说,整个操作系统就是一个整体,包括了进程管理、内存管理、文件系统等等,而对微内核来说,操作系统的大部分在内核之外,彼此间通过消息进行通信。

之所以谈到宏内核与微内核之间的关系,这是由于“过程调度”“流程引擎”“应用处理”之间的关系决定了对于过程引擎的设计,必然牵扯到“微内核”与“宏内核”的考虑。

 

很多设计人员在设计流程引擎的时候,一般是以“微内核”设计为指导思想的,正如上面左图所示的那样。但是往往在后期,随着应用的复杂度增加,客户业务需求的特异化,造成最终的流程引擎可能是右图所示,从而最终偏离微内核的宗旨了。

造成这种现象的主要原因是由于目前对于流程引擎的组件设计、接口描述等多方面都没有形成“一致的标准”,也就是:一个引擎不是孤立的,其必然也是有很多组件、服务接口、规则等多方面组成的。这些组件之间需要通讯,但是并没有一个统一的规范能够约束这个通讯机制和数据,所以最终都依赖于各个厂商自己的实现能力和抽象能力。

这并不像我们所熟知的Jboss App Server那样,其依赖于JMX这个规范标准,从而构建了一个完美的“微内核”服务器。所有的服务和组件都通过实现JMX的接口挂接在这个微内核构架之上,组件之间的调用和数据交互头依赖于统一的标准。

虽然,现阶段我们很难构架一个过程引擎能够百分百实现纯粹的“微内核”,但是,通过“微内核”这套设计思想的指引,并不断对引擎内部的组件进行抽象、提炼,对服务剥离和重构,来逐渐减少业务应用与过程调度之间的耦合度。

微内核过程引擎的构架

两年前写过一篇名为《微内核工作流引擎体系架构》的文档,文档基本阐述了微内核工作流(流程)引擎的几个层次和相应的一些解决方案。这份文档可以在我的主页www.javafox.org上免费下载。

微内核引擎的原则,就是尽量将“引擎所需的服务”与“引擎内核调度计算”剥离。将Engine Kernel部分尽量“疏剪”,尽可能将“一些处理操作”放置于外围扩展。

上面这张图,可能会在很多产品介绍或者工作流文章介绍中看到类似的,但是很少会有提及“过程引擎”结构这一部分的。

微内核的过程引擎结构,一般主要围绕三个层面构建:

(1)引擎内核处理:这就是引擎真正的Kernel了,在一层最主要解决的问题就是:流程的调度和执行。
(2)引擎执行服务层:为引擎提供一些公共服务和资源处理。
(3)扩展实现层:这一层是微内核最为繁琐地方,有各种扩展点供外围扩展。总结下来主要有三类:
a) 支撑流程运行的:这些扩展点必须被实现,否则引擎无法运行。比如为引擎提供存储适配。
b) 辅助流程运行的:利用这些扩展点,可以让引擎进行更多的处理,比如一些Function接口、条件处理接口。
c) 增强流程运行的:利用这些扩展点,可以让引擎的内能变得更强大和完善,比如一些事件监听处理接口,客户自定义的策略实现等。

“微”内核

总的来说,微内核有两层含义:

(1)支持功能非常简单:仅处理最核心的过程调度相关的功能。也就是说,当有一个节点完成的时候,这个过程引擎的内核,能够准确的依据已经过程定义,并按照事先构造的调度算法和机制,来计算下一个需要执行的节点。

(2)实现的结构非常简单:没有太复杂的实现,但都会有几个最基本的对象体。

从实现结构上来说,没有太标准的规定,基本上每一个引擎都会有所不同。大家可以拿jBpm、OSWorkflow及OBE这三个引擎比较一下,基本上结构都是不一样的。限于文章篇幅,就不在这里详细分析这三个开源引擎的结构了,大家可以参考我曾经写过的那篇《工作流引擎核心调度算法》,里面有部分内容涉及到结构上的比较。

虽然结构上可能会差别很大,但是基本的实现思路和基本的关键对象体是或多或少有些相似的。

(1)       每个引擎内核都是提供一个ExecuteContext(执行上下文)对象来负责每一个实例的环境信息。
(2)       每个引擎内核都会提供一个机制,这个机制用于计算流程的流向。这个机制会因为采用不同的算法和思路差别会很大。
(3)       每个引擎内核都回提供一个执行机制,这个机制用于执行那些“允许被执行的节点”
(4)       每个引擎内核都回提供一组最内核的实例对象来表示流程实例的可持久化信息

结尾

短短的五千字很难把微内核过程引擎的设计思路和构架讲解清楚,很多内容只能“蜻蜓点水”的掠过。过程引擎的设计需要融合“理论”和“技术”。不仅需要对软件开发有着深邃的理解,还需要有工作流的基本理念、概念、过程建模方法、系统结构等多方面的理论基础。

 

组织简介 | 联系我们 |   Copyright 2002 ®  UML软件工程组织 京ICP备10020922号

京公海网安备110108001071号