BPM平台在各行业的IT架构中都是重要的基础支撑平台,十二五期间,企业级BPM作为SOA体系下的关键组件,经历了一个加速建设的过程。我们也有幸参与了一些行业的流程平台建设,今天与大家分享我们在流程引擎架构演进过程中的一些经验与思考。
首先对过去这些年的架构发展历程进行回顾和总结,
然后谈谈目前单体型BPM遇到的问题与微服务改造的思路,
第三部分介绍流程平台向微服务架构演化的一些思考与规划。
过去:企业级BPM十年架构演化回顾
自上世纪60年代起,企业运营中的管理需求不断推动着流程管理思想以及流程技术的发展,首先是信息技术驱动的流程自动化思想出现,然后职能部门的组织模式问题促使BPR业务流程再造的出现,来到21世纪初,以业务流程为中心组织企业整体运营的思想逐渐被接受成为主流,推动了BPM技术的发展。
工作流时代,主要在单个业务系统内部实现流程的自动化与灵活变更,解决较小的企业和组织的流程自动化需求。而BPM技术是在完整的思想与方法论体系下诞生,站在全局视角关注企业的战略落地、职能打通、敏捷响应,是涵盖业务流程建模、执行、监控、优化的全生命周期解决方案。
如果您于十几年前就开始接触流程领域,这一定是您记忆中深刻而又古老的一张图,大多数早期的工作流厂商均是参考该模型制定了自己的产品架构。无论技术趋势如何演变、功能需求如何叠加,流程平台的总体概念架构并没有脱离这个参考模型。
该模型的核心是流程引擎,以及由其提供的5类接口,流程引擎实现了核心的流程调度机制,支撑着流程模型及其组成活动的定义、加载、解析、校验、执行、监听的整体运行过程。本次分享主要针对流程引擎的架构演化来展开。
本章节对过去这些年流程平台的架构演进历程进行回顾,从两个纬度分成两条演进路线来讲述。
第一条线是功能性架构,从最初只能支持单个业务系统的内部工作流,到打破部门墙支持端到端流程,再到SOA体系架构下全面支撑企业的流程建模、实施与监控,从支持WfMC-XPDL到支持BPMN规范,最后对大型企业的多领域业务系统进行集中纳管。
第二条线是非功能架构,利用集群、缓存、异步、分布式等多种架构模式,不断追求着高性能、高可用、可伸缩性等质量属性。
十多年前,工作流的应用刚刚在国内兴起,一些开源的工作流引擎诸如jbpm2.0、osworkflow开始被广泛使用,那时大多是嵌入式架构,即流程组件与业务系统部署在一个应用中,只做本地调用,共享一个数据库,只能实现该业务系统内的工作流自动化。
随着流程领域的深入发展,流程平台开始作为一种中间件进行独立的部署和运维,业务系统通过远程调用的方式获得流程服务,依赖单独的流程数据库,流程管理控制台也被当做一个前端应用分离出来。这种部署架构显然是更加复杂了,但却是从工作流走向BPM的关键一步。
因为BPM的目标是将多个业务系统间的流程连在一起,将多个业务应用中的流程集中管理,其所服务的对象也不仅仅是开发人员而是面向企业管理。定位的不同,带来架构与功能的诸多不同,BPM所要解决的问题要求其必然是独立部署的。
SOA是面向企业架构的一套方法论,BPM与ESB都是其体系下的重要支撑平台。ESB是系统间服务接口交互的总线,可以做服务路由、协议转换、报文转换、逻辑编排,但它处于技术层面的互联互通。
BPM则是站在全局业务管理的视角实现一个更高纬度的集成,在这一架构下基于SDO/SCA技术的BPM可以实现动态web服务,并且更加方便的接入ESB上的服务,在端到端业务流程集成方面的支撑力度更强。
十二五IT建设期间,许多大型的国企央企都提出了企业级BPM或统一流程平台的概念,借此契机,流程引擎开始向着多租户架构发展。
企业级BPM是指在公司总部及各省(市)公司构建集中的“BPM流程服务资源池”,将原来由各应用使用的BPM组件统一收归至总部及各省公司集中部署与运维,集中纳管各系统流程模型及流程运行实例,体现出“统一流程标准、统一流程服务、统一流程运维”的特征。
每个应用的流程独立流转互不干扰,支持表级数据隔离、数据源级隔离,支持租户的组织机构服务、任务推送服务等十几项个性化配置。
PVM即流程虚拟机大概是在2009年开始在流程领域出现的一种技术,是一种优秀的程序可扩展性架构。PVM本质上是要将流程引擎与流程语言解耦,为此,PVM提供了一套独立的流程定义模型、插件环境及插件扩展点。
流程模型与任何流程标准或规范无关,直接决定了PVM对流程的描述建模能力,也是支持多流程语言的关键。从PVM的扩展机制可以看到,模型是保持不变的,能扩展的只是节点的运行期行为。
PVM提供了一套插件环境以及插件扩展点,把流程与活动在运行期的关键行为抽象出来,与流程的其他模块解耦合。最后,PVM还提供了一套调度框架或称持续推进机制,使流程可以持续运行或从任意一个点重新切入。
在高并发、大吞吐量的应用场景中,需要能够水平扩展的集群架构,负载均衡将来自业务系统的请求分发到集群中的某个流程引擎,每个引擎保持着自己的状态数据(如流程实例等),在多个引擎的本地缓存间需要同步状态,在引擎内部以及集群的多个引擎之间需要对并发请求进行排队,这种分布式缓存的方式也是redis和memcache等集中式缓存没有在企业应用中被广泛使用之前的主流选择。
对于集群架构的支持除了缓存数据的状态同步,还需要全局锁机制、集群通知机制、统一主键生成机制、业务资源同步机制、任务争抢机制等,系统的每个模块在设计和研发中都不能忘记自己是在一个集群中运行的。
随着流程平台逐渐应用于电信、电力等行业的关键生产系统中,对于性能和可用性的要求迅速提高,基于SEDA理念的三段式框架应运而生。
SEDA是为了支持大规模并发处理、降低响应时间、处理请求积压以及隔离外部系统不稳定性而出现的一种架构模型。其核心思想是把一个请求处理过程分成几个Stage,不同资源消耗的Stage使用不同数量的线程池来支撑,Stage间使用事件驱动的异步通信模式。
流程平台基于自身的应用特点可以将引擎分为三段:接入段、引擎段、接出段,在支持原有的request-response同步调用方式之外,接入段与引擎段支持One-way方式,引擎段与接出段间支持request-callback方式。
平台的异步api接口、ServiceTask/SendTask图元、异步触发事件等功能模块都可以基于三段式框架来实现。
分布式SEDA架构则是通过非阻塞的HTTP调用来组合多个SEDA架构的JVM,这些JVM可以在一台机器上,也可以分散在多台机器上。
对于一个请求的处理被分为6个Stage:接入层(正常响应Stage/异常响应Stage),流程引擎层(请求Stage/正常响应Stage/异常响应Stage),接出层(请求Stage)。 接入层根据请求中的流程实例ID和集群节点数的余数进行路由(PID%NODE_NUM,限任务提交等非统计查询类操作),可以传递给本地JVM流程引擎或是远程JVM流程引擎,待处理完成后,将真实的业务数据响应返回。
现在:单体型BPM的问题与改造方案
架构的演进是在众多行业客户的需求推动下对功能性以及质量属性的不断追求。在功能性方面,工作流自动化、端到端流程打通、多系统集中纳管;在质量属性方面,为获得更低的延迟、更高的吞吐量,采用并行化、异步化、批量化、缓存化、去中心化等架构模式,无单点的可用性设计,服务器、缓存、存储各个层面的可伸缩性,不断的服务分层、模块分割构造出程序面的可扩展性。
然而,对于一个发展了十余年的单体巨石型平台系统,庞大的代码量和众多的公共模块,导致回归测试工作量激增、版本发布周期长、新同事接手难、产品质量难以保障。
不同模块有着截然不同的计算特点,有cpu密集型、内存密集型、IO密集型,有主体核心的功能,也有繁杂的衍生功能,垂直架构下这些模块均部署在同一进程中,相互影响的矛盾似乎难以调和。
而企业级BPM统一流程运行服务的功能需求对于弹性伸缩、高可用、热部署等能力需要在对等集群架构下也遇到了技术瓶颈。图中对BPM在研发运维中经常遇到的问题进行了举例,后续章节将尝试通过微服务架构改造来解决。
互联网经济深刻改变了我们身边的商业环境,消费者的生活方式日益数字化。企业也在运用多种技术手段发挥数字化潜力,促进企业业务模式的转型。这要求IT架构更快速的响应客户的个性化需求,更加弹性的应对无时不在的客户请求。
架构规定了软件的高层划分及各部分间的交互。太多问题矫揉在一起会造成解决方案的复杂度陡增,所以架构设计很重要的一点就是能把难以处理的大问题分解成便于管理的小问题。架构是为管理服务的,能够把软件拆分成稳定的细粒度模块的架构就是好的架构。
在企业架构上使用SOA支撑业务,而在应用技术架构上使用微服务架构,是一个合适的选择。
服务化的思想一直是软件架构的标准范式,微服务则是这一思想的最新实践,它会给我们带来哪些启示呢。图中列举了微服务架构的9个特征(Martin Fowler),以及对微服务可能带来的价值进行了举例。一直关注我们微信群的朋友应该不会陌生。诸如每个微服务独立开发、独立伸缩、故障隔离等也是企业级BPM所急需的。
经过微服务架构改造的系统会变得更加复杂,这种复杂性体现在一个软件的全生命周期的所有环节,业界大师Martin Fowler建议微服务要基于一个基础平台最好是一个PaaS平台。
其实不仅是PaaS,这个平台需要涵盖DevOps、容器云、微服务框架三个领域,DevOps平台用于支撑微服务的全生命周期数字化协作,容器以其不可变性和自给自足的特点成为微服务部署与运维的最佳选择,微服务之间通过分布式调用框架所提供的服务注册发现机制、服务路由、集群容错等特性以去中心化的方式进行协同。
改造过程中会参考云原生应用的12准则,后文的微服务拆分中有所体现。后续概念图中可能会出现基础平台的一些组件,我们基于重基础架构(平台)、轻应用架构(服务)的理念以求最大限度的屏蔽微服务架构带来的问题。
我们从业务能力、技术服务、数据实体三个层面对BPM平台进行详细的梳理,并对三个层面间的支撑关系进行整理,根据梳理的成果以及对系统长期的研发与运维积累下来的经验,识别出可以拆分出来的且拆分后可以带来价值的微服务。下图简要展现了梳理的内容。
根据业界前辈Chris Richardson对微服务模式的介绍,我们可以根据动词或名词进行微服务拆分,动词用于服务划分,名词用于资源划分,负责特定数据实体的一系列全量操作。从动词和名词的角度考虑三个层面的梳理,前两个层面多是动词,数据实体则偏向名词。
这里还想再提一点,在过去的十年里,我们的BPM平台经历了几次代码重构与架构优化,层次清晰、内部技术服务间的边界很稳定,前后端也实现了分离,这些都是微服务改造的良好基础。如果您的系统是一个新的系统、正在快速变化的系统,需求变动与代码重构都可能会使模块间的关系很不稳定,做微服务化的难度会加大。
Œ未来:企业级BPM的微服务架构演进
第三部分讲述我们对企业级BPM进行微服务架构改造的一些规划和思考。
微服务的划分原则有着不同的实践,可以从不同的视角、不同的关注点去分析,而它们有时又是交叉的,该图展示了我们在思考微服务拆分时的几个维度。
名词/动词视角,例如可以将工作项(参见WfMC-XPDL流程定义元模型之workitem)这个名词及其相关的全量操作分离出来,这也相当于把PVM的一个图元插件的实现拆分了出来,也可以将自由流转到目标节点这个动作分离出来,自由流是典型的中国特色流程需求,其主要目的是打破流程图的原有定义,更加灵活的动态流转。
业务能力/技术服务视角,对于一个业务系统而言,这相当于纵向拆分和横向拆分。站在流程平台这个系统的角度去看,自由流、指派后继活动参与者等直接以对外api方式体现的能力相当于业务能力,而业务规则引擎、主键生成服务、定时器服务等都属于后台的技术服务。
主体功能/衍生功能视角,例如PVM的流程调度/流程持续推进能力是平台的主体功能,而任务推送、转历史等都属于衍生功能,没有这些能力并不影响正常的流程推进,然而事实上它们在运行中的不确定性会极大影响PVM的性能。
我们一直在思考BPM该如何更有效的向微服务架构演化,结合BPM产品自身的特点与一些业内经验,我们暂且列出这些原则,后续拆分示例中会有所体现。
此处先简单说明几点:
集群化是指由过去的对等集群架构演化为所有微服务都可以动态伸缩,这可能涉及到负载均衡由前端单点转移至调用方;
去中心化涉及到服务的协同方式不再走集中式的ESB而是选择发布订阅模式,包括注册中心本身也要去中心;
配置化包括服务的依赖关系解耦,对应用透明无侵入;
版本化指在服务升级或线上bug修复等场景下所需要的多版本管理,服务的提供者与消费者在发布引用时须指定版本号。
云原生应用12准则之一是将应用作为无状态的进程来运行,无状态才能保证应用可以随时启动和关闭,可以根据压力动态伸缩。压力监控与伸缩漂移等能力都由基础平台提供。
无状态并不是真的没有状态,而是将数据状态保存在基础平台的缓存服务中,对于业务系统而言状态可能是session,对于流程平台而言则是流程实例缓存等。这也涉及到云原生应用准则的“后端支撑服务”,将数据库、缓存、消息队列等这些后台支撑服务当做可挂载的资源,对应用透明。
BPM现有的分布式缓存机制是使用JVM本地内存并通过集群通知或全局锁机制处理缓存的变更。如果不走无状态改造这一关键步骤,上云后在功能方面可能会出错、在性能上也达不到伸缩的效果。
除了流程实例缓存,还有流程定义缓存、代理关系缓存、业务资源缓存、业务规则缓存、多租户缓存等所有需要集群同步的数据都需要放在基础平台的集中式缓存服务中。各类缓存的原接口保持不变,实现类则改为调用基础平台缓存服务的SDK获取各类数据。
组织机构服务在工作项处理等模块中会被频繁使用,BPM提供接口供业务系统接入时实现,比如在国家电网的实现是统一权限系统ISC。考虑到该接口十分重要且依赖外部系统的稳定性,出现问题时不容易厘清原因,并且有热更新的需求,可以将组织机构服务拆分出来。
图中演示了使用蓝绿发布来实现热部署的过程,主要是三个步骤:部署新版本,导入测试请求,切换流量将生产负载路由到新版本,客户端负载的路由可由基础平台的微服务框架提供。
任务推送表是工作项处理模块与任务变更推送模块之间的共享模型,该模型对于工作项模块是频繁的实时的修改,对于推送模块是定时的批量的处理,鉴于当前的处理方式可以不对该表做迁移,只把推送服务迁移到独立进程中。
推送的技术实现是租户即业务系统的个性化配置,也就是说这个模块受外部系统的影响很大,当它运行起来但远程推送过程中出现不稳定状况时将影响PVM主体的性能,因此将作为衍生功能的任务推送模块拆分为微服务可以起到隔离外部故障的作用。故障隔离不使整个系统陷入瘫痪也是微服务架构的价值之一。
业务规则引擎是BPM平台的一项基础服务,PVM做流程调度时基于它计算分支,工作项模块生成人工任务时基于它计算参与者。
业务规则引擎由规则缓存、规则编译、规则执行三个主要的部分构成,可以整合拆分为一个微服务,对外提供的接口直接返回规则执行后的结果,可能是一些参与者也可能是布尔值。规则编译所依赖的库表可以不拆分,规则缓存如上文所述需要转移到基础平台的缓存服务中。
自由流、顺序工作项、指派后继活动参与者三个功能模块均由流程实例属性表所支撑,其中自由流和指派后继活动参与者都是可以独立接收业务系统api调用的。
可以把流程实例属性表及缓存连同这几个功能单独拿出来,表也可以放在原库。该模块内部调用关系比较简单易于拆分,但这几类api的调用量比较低,拆出来的价值还需要评估。
从这个例子可以看到,在没有拆分微服务之前,因为代码都放在一起,很难意识到把不同的关注点放在了一起,现在可以将某些数据分离为单独的表,或把某些表分离为单独的库。这引出了微服务架构所带来的数据一致性问题,这个问题首先是尽量避免出现,在其他同事的分享中提供过几种解决方案。
本例在一个事务中可能会同时更新流程实例表和流程属性表,我们可以采取重试+补偿的策略:如果更新流程属性表失败,尝试一定的次数,仍不可用则在主体程序中抛出异常(该模块也可以熔断或降级,当判定其不可用时,流程引擎的主体能力不受影响),如果流程属性表成功,流程实例表的事务失败,补偿流程属性回退到操作前的状态。
工作项是一种重要的数据模型,按照名词做资源划分可以将其以及相关的全量操作分离出来,对于主体PVM而言只是人工任务这个图元插件的主要实现程序被拆了出来。
工作项微服务既可以直接提供api服务(负载的路由问题可以由API Gateway支撑,这也是一种常见的微服务模式),也可以为PVM提供内部服务,而且finishworkitem这个操作有可能回调PVM主体,用于在工作项完成时触发流程推进,所以二者是双向调用的关系。
异步化是常用的性能优化方式,在合适的场景下,异步化可以带来更大的吞吐量、更短的响应时间,而且还具备隔离外部不稳定性的作用。此处触发事件以及ServiceTask/SendTask等功能都可以基于SEDA组件进行异步化调用。
BPM引擎对外API以及内部服务器之间的调用,都统一使用RESTFul,可以方便的进行服务mock以及监控分析。
基础平台的API Gateway组件以及服务注册中心用于将客户端的请求路由至微服务架构中的可用服务实例。这种模式可以确保客户端察觉不到应用程序已经被拆分为多个微服务。
由平台提供的基于注册发现机制的分布式调用框架将确保客户端不受服务实例位置的影响,即当某个微服务做了伸缩、漂移、熔断、降级等操作之后不影响客户端对其寻址。
本次分享针对企业级BPM平台做了一次微服务架构演进的思考,每个领域的it系统它的运行方式、计算特点、架构风格都是不同的,深入理解自己的系统,才能选择最合适的方式进行微服务架构探索。
普元云计算专区:http://primeton.csdn.net/m/zone/primeton/index#
普元公众号: