技术开发 频道

详解SOA五种基本架构模式

模式四:工作流化模式

    我曾经为一家移动公司做过一个项目,构建一个售后服务系统。大家应该都知道,移动公司之间的竞争是非常激烈的。竞争的结果就是,这家公司的销售部门经常要夜以继日地工作才能制定出新的使用方案或捆绑销售计划以提高销售额:比如朋友、亲情、PTT的公司业务、更低的国际电话费用等方案,3.5G网络的捆绑推广等。对于这家公司来说,每周都会有好几种新式应用方案产生。其记账系统是基于Amdocs的,SAP系统应付新方案也很轻松。然而,市场竞争通常都是从销售部门开始的,而不管IT部门的就绪度如何,因此如何尽快地支持新的销售流程就成了迫切的需求。

    几乎所有企业的业务需求都是不断变化的——虽然可能不像前面所描述的那般迫切,但它毕竟是存在的。我们必须寻找一种方式让我们的服务适应这些不断变化的过程。

    问题

    如何提高服务对不断变化的业务流程的适应性?

    最容易想到的方法是每次都等待变化的需求,然后根据需求变化开发代码,更新服务。这里有几个问题。首先,为了变更需求,你需要一个完整的开发周期。其次,代码变更意味着系统的很大一部分需要重启——想一想一些诸如此类的问题吧:“我们昨天的计划会不会受到这次更新的影响?”;“会对上个周期我们添加的那个类似的东西产生什么影响?”等等。可以说越多的开发和测试就等于越长的上市时间。在我们的项目中,这意味着实施新的计划需要几个星期的时间,这会让管理部门很不高兴。这也意味着你的工作评定又降了一级,甚至更多。我们当然不能这么做。

    一个较好的办法是将应用中比较稳定的部分从经常改变的部分中分离出来。比如在我们的方案中,像顾客姓名、地址等人口统计资料应该就是与销售方案无关的稳定因素。虽然如此,编排稳定的逻辑仍然是一项繁琐且容易出错的任务。或许,我们可以想个更好的办法……

    解决方案

    在服务中引入一个工作流引擎来处理不稳定的和经常变化的过程、以及编排稳定逻辑(stable logic)。

    如图9所示,工作流化模式是在服务中添加一个工作流引擎来驱动业务过程。工作流引擎中包含一个工作流实例(workflow instance)。最基本的形式是每个工作流负责一种请求类型;然而,工作流可以更复杂,处理连续的过程并且有多个接收外部服务请求或数据的入口点。

    

    使用工作流的优势是可以以活动为构建块进行思考,从而更灵活、更轻松地安排流程。以活动流的方式建模过程意味着可以更容易地分辨并重用稳定的部分,直到有变化需求为止。既然活动可以进行自我测试,重用一个活动就代表你不用再进行大量的测试。而灵活地重新安排活动则代表你可以迅速地响应业务需求。

    这个能够更容易地(通过工作流)改变服务行为的诱人方案有一个问题:每次行为变更是否需要同时更新契约版本?回答当然是要看情况。我的原则是,对于契约行为来说,如果里氏代换原则成立,那么就不需要添加新的版本。

    什么时候更新契约版本——里氏代换原则

    里氏代换原则,或契约式设计,是一种面向对象的原则。Barbara Liskoy(里氏)是这样说的:“如果对于每一个类型S的对象o1都有一个类型T的对象o2,使得以T定义的所有程序P在所有o1都被替换为o2的时候程序P的行为没有变化,那么S是T的一个子类型。”简单地说,这就是指子类可以代替父类使用而不会破坏任何使用基类的行为。应用到SOA上这意味着改变服务的内部行为时,如果对于每个契约中定义的操作,前面的情况不变或较弱,而后面的情况(比如请求结果)不变或更强,那么你就不需要创建新的契约版本。换言之,为了保持相同的契约版本,新的服务版本应该与客户对旧的服务版本的期望行为保持一致。

    下面我们把示例的场景工作流化,看看工作流是怎么发挥作用的。简单重复一下,该场景主要是关于如何更快地为移动公司引入新的使用方案。在引入新的方案的时候,后台系统通常还没有就绪——一般需要几天甚至几个星期的时间进行改动、测试和部署。而使用工作流的一个优势就是可以在没有后台的人工干预的情况下为新方案提供请求路由支持。比如,我们可以先让客户关系管理(CRM)系统记录某个客户服务的变更,通知技术人员配置网络等,然后等后台系统就绪了,再更新路由把流程指向新系统。此外,正如前面提到的,在这个流程中有许多步骤是稳定的,比如获取客户的人口统计数据(姓名、地址等)、为电话提供附加程序或附件等。这些步骤都是可以被几乎全部销售过程重用的活动或步骤。在这个场景中添加一个工作流可以极大地提高业务响应能力并保持业务敏捷性。如果某个竞争对手启动了一个很受欢迎的新方案,那么这家公司就可以在一天之内回应一个有竞争力的方案。这是真正的有形商业资产。

    工作流引擎的另一个优势是能够处理持续的过程。它把涉及多信息交互的全部过程直观地表示出来,使我们更容易对蓝图和过程有一个清楚的了解,因此可以从业务的角度来调试过程。

    当然,工作流化也可以与其它模式结合。比如,很容易通过作业调度(几乎所有的工作流引擎都支持)实现主动式服务模式。

    流程编排(Orchestrated Choreography)是一种与工作流化密切相关的模式;这两种模式都使用相同的底层技术:使用工作流引擎。不过,虽然底层技术一样,但是不同的架构考虑方式却会导致选择不一样的模式。比如,两者之间一个很明显的不同就是工作流化局限于一个单独的服务中,而流程编排则需要在服务间添加调整性工作流。

    技术相关

    这一部分我们将简单的了解一下利用当前的技术实现这个模式的意义以及实现模式所涉及的技术。

    与工作流化模式相关的技术自然是工作流引擎。当前市场上有许多工作流引擎。微软将Windows Workflow Foundation作为.NET 3.0的一部分,我觉得这会让它在.NET世界中很受欢迎——虽然还有几家其它公司为.NET提供了像Skelta或K2之类的工作流方案。Java自然能得到更多公司的支持,比如IBM、JBoss,以及专业的工作流公司Flux等等。Oracle甚至提供了一个工作流包(数据库WF_Engine)和Java API支持。

    大多工作流引擎都有内置的用以修改工作流的可视化设计器。图10是主动服务模式下用以生成报告的Flux的可视化设计器。

    

    使用像图10所示之类的编辑器是修改流程的不错选择,通常你还可以使用XML来定义工作流。还有一些工具,比如开源(BSD许可证)OpenWFE,完全不提供可视化编辑器,只能依靠XML来配置工作流。下面是一个在OpenWFE中编辑流程的示例。

    例1:OpenWFE中信贷审批工作流的部分XML实现

<process-definition name="Credit approval">
    <sequence>
        .
        .
        .
        <participant field-ref="order_value" />
        <if>
            <greater-than  field-value="order_value" other-value="10000" />
        <!-- then -->
            <sequence>
                <participant ref=”supervisor”/>
                <subprocess ref=”ReviewAndApproveOrder”/>
            </sequence>
        <!-- else -->
            <subprocess ref="TaskPaypal" />
        </if>
        .
        .
        .
    </sequence>
</process-definition>

    选择工作流引擎——灵活性

    编辑工作流可以考虑几个简单的模块,比如活动、异或分支(可能的执行路径之一)、并发分支。要注意有时候会遇到更复杂的场景,像如何在不同步的前提下合并多个执行路径,并且只执行一次后序的活动,还有如何处理一个活动的(各个活动需要同步的情况、活动数量无法预知的情况等等)多个实例,以及许多其它此类问题。这些问题的解决方案就是工作流模式(在“工作流模式页面”上有描述,详见http://is.tm.tue.nl/research/patterns/patterns.htm)。

    我的建议是先了解一下引擎支持哪些工作流模式以保证良好的灵活性,而不会在后期走进死胡同。虽然灵活性并不是唯一的选择标准(还得考虑性能、可用性、安全性等),但我觉得作为一个以灵活性为前提而选择的工具而言,灵活性是一个非常重要的标准。

    某些工作流引擎,比如Microsoft Biztalk或WebSphere MQ Workflow,相对内部的工作流成本来说,更适合编排内部服务的交互。

    质量属性场景

    这一部分是从需求的角度讨论使用模式的架构效益。大多架构需求是通过使用场景表现的质量属性(可扩展性、灵活性、性能等)来描述的。这些场景也可供其它可以应用模式的情况参考。

    工作流化的主要优势是能够提高灵活性。设计一个工作流是一个可视化过程(至少大多工作流实现如此),很容易掌握。附加的灵活性优势也能在需求改变时加快上市时间。在我看来,工作流是使服务走向敏捷业务的最重要的工具。

    下面是几个场景,可以给你考虑使用工作流模式的理由。

质量属性(第一层)质量属性(第二层)场景示例
灵活性添加过程对于所有预付费方案,添加对新方案的支持只需要两天不到的时间。
重用性核心模块每个新方案可以重用90%以上的常用销售过程

     由于你可以动态地改变服务行为,因此工作流化模式能够提高服务的灵活性;另外还可以提高边界组件模式的灵活性。

1
相关文章