简介
本页面描述了使用基于 BPEL 的编排技术且以 SOA 风格构建的应用程序。在此项目的设计和开发阶段中获取的经验能够为其他人考虑使用基于 BPEL 的编排(以 SOA 风格)提供总体认识。
这里使用将业务需求和现有应用程序元素纳入考虑范围的 Pros 和 Cons 比较来对设计方法进行评估。 本页面包含了一些设计建议,还确定了建议使用 BPEL 驱动方法的特性。
已获取的经验
-
在工作流与伙伴服务之间选择正确的业务逻辑分段有时候很有挑战性,并且在任何情况下都很重要。
业务逻辑在基于工作流的编排和伙伴服务之间区分。伙伴服务最终应当负责计算密集型逻辑或复杂逻辑;而编排则包含了为响应业务需求变更而期望变更的逻辑。
由于这并非始终是一种清楚的区分方法,所以设计应程序,通过修改工作流和添加新的伙伴服务(而不是修改现有的伙伴服务)来使其演进不失为一种有用的补救策略。
从根本上说,这是一种迭代方法。早期的原型可能需要重构伙伴服务才能完成可通过添加新伙伴服务进行演进的设计。
当然,在任何情况下,都应当将不必要或从不变更的代码排除在工作流之外。
-
利用 BPEL 的独特功能
BPEL 能够对显现各种不同绑定的伙伴服务进行编排。
绝对不要在特定的服务实施或伙伴服务绑定的特性上构建依赖关系。 这么做可能会使以后对编排或整个应用程序的变更变得复杂化或产生限制。
请考虑将 BPEL 变量内的中间结果保留为策略以提高性能
-
尽可能地设计无状态方式且具有幂等操作的伙伴服务。
为了便于讨论此主题,幂等性仅表示某个服务可通过同一输入数据多次调用,并且期望同一响应对每个调用都正确。 此特性能够显著地简化调用者和服务,这是因为它极大地简化了交互过程。
错误恢复、故障后重新启动、通过集群缩放全都得到了简化。对于调用者,网络、服务器和客户机问题的错误恢复得到了简化。 幂等性是衡量伙伴服务的 BPEL 编排是否潜在地良好匹配的一个重要指标。
当然,如果需要更复杂的交互,则 Web Service 协议包含可在此类情况下采用的补偿功能。 在所有因素都一样的情况下,如果您能够在整个应用程序设计中避免此类需求,则结果将更易于维护和测试。
用例研究
此用例研究描述了 IBM 项目如何对其 ServicePac® 业务所使用的信息技术进行升级。此项目的目标是缓解特定的弱点并对 ServicePac® 业务在规模和功能上的继续扩展进行定位。
与许多成功的业务相似,IBM 的 ServicePac® 业务已经历了一系列的递增式转换,一开始是按地理区域将许多截然不同的担保规划组合成三项业务。 然后,将不同地理位置的业务组合成一个单独的全球业务。这些年来,ServicePac®
业务不断增加新的产品(例如安装服务和产品)以支持新的 IBM 硬件。虽然 ServicePac® 业务本身是一个单独的全球业务,其产品 ServicePacs® 通过众多的 IBM
业务和业务合作伙伴渠道进行销售。每个销售组织有其自己的订单输入系统,此系统是根据各自的业务渠道而定制的(并非根据 ServicePacs®)。这些系统由不同团队在不同的时间采用不同的技术构建,代表了真正的“度身定制”。
处理 ServicePacs® 的订单输入系统必须根据由 ServicePac® 业务开发的需求对订单输入时间执行验证。ServicePac 验证可能会相当复杂。在 100 多个国家或地区提供了
ServicePacs®,但每个国家或地区的产品不尽相同。 ServicePac® 产品因产品模型、交付的国家或地区、销售渠道、订单输入系统以及特定于客户的信息(例如当前拥有的 ServicePacs®)而不同。
传统上,ServicePac® 订单验证已在订单输入系统内执行(仅实施该系统支持的销售渠道所需的那些验证)。 随着 ServicePac® 业务的发展,用于交流验证需求,协调其开发、测试和部署的成本已变得过于高昂。
而且,在订购系统中安排合适的订单验证明显延长了新产品的上市时间。
图 1 - 面向服务的“ServicePac® 订单验证”方法。此方法用于向负责处理 ServicePacs® 的所有订单输入系统启用单一的服务,而不是在每个订单系统中逐个放置特定的验证逻辑。
面向服务的验证方法
在早期,显然验证是 ServicePac® 业务的职责,但并非通过每个单独的销售系统对 ServicePacs® 进行订购。有两种方法供考虑,一种是将封装了订购验证需求的代码分发至所有的订单系统,另一种是提供一个集中化的订单验证服务。
选择集中化的服务方法的主要原因是为了避免与分发代码方法相关的管理问题。
将“订单验证”显现为订单输入系统中的一项服务的最大好处就是订单输入系统不再需要本地实施、测试或运行自己的 ServicePac®
订单验证逻辑。而最大的问题(或担忧)来自许多订单输入系统的所有者,他们现在对由其他组织操作的外部系统具有新的运行时依赖关系。 您将在下面了解到,将验证逻辑提供为一个服务的重要性超过了本例中的相关问题。
以下是对该项目体系结构目标的快速汇总:
-
接口设计:验证接口需要设计为平稳地处理预期的业务演进(例如,提供的新产品一般不应要求任何接口修改)。
-
消息传递协议独立性:验证服务应当可独立于调用平台、编程模型、网络传输层或硬件选择被访问。
-
业务灵活性:实施了验证逻辑以使预期的业务变更在不牺牲性能、稳定性或违背基本设计规则的前提下变得安全、廉价和快速。
-
可伸缩性:提高吞吐量应无需重新编程或重大的功能测试。
接口设计
通过与管理产品术语的所有团体的业务所有者和业务架构设计师合作,为当前和预期中的产品开发了一种前后一致且记录完整的分类法。 根据此分类法,开发了一个以 XML 模式语言描述的 XML 数据模型,它描述了所有必需的产品类型及其属性。
随着新产品的提供,分类法可变更(以及潜在模式的变更);但是,只要新产品属于已定义的分类法范围之内,实际消息格式就应当保持不变。
此方法为业务提供了所需的灵活性,使其能够迅速和廉价地引入新产品。 当然,它并不涵盖所有可能的情况。例如,如果新产品具有一个前置条件,而在现有的消息定义中并未包含该前置条件,则必须相应地添加新的消息定义。
在列表 1 中,显示了一个简单的验证请求消息有效内容,其中包含了一个订单,它针对一台客户拥有的计算机(通过其部件号和序列号确定)的单个 ServicePac®。该消息格式支持针对多个 ServicePacs®
的多个订单,它们可以与新硬件和现有硬件关联。 在某些情况下,消息可能具有几千个内嵌的元素。
消息传递协议独立性
使用 BPEL 的重大好处之一就是服务之间的消息传递关系是以 WSDL 抽象地描述,而 WSDL 提供了一定程度的消息传递协议独立性。 要最大限度地利用此特性,就必须在开发期间小心谨慎,以避免构建依赖于所用消息传递协议的特定特性的实施。
例如,如果在开发期间使用的是 EJB 绑定,则该编程风格可能导致短且不连贯的消息交换(即小型消息的频繁交换)。 如果以后该绑定变更为 JMS 或 SOAP over HTTP,则可能出现严重的性能瓶颈,这是由这些协议的较大消息开销导致的。
在此情况下,可通过遵循一种消息交换为详细程度低(即较不频繁地交换较大的消息体)的编程风格来减少在各种绑定间移动所产生的影响。
<?xml version="1.0" encoding="UTF-8"?>
<spkOrderDataList>
<header>
<orderReference>1040-5124-001</orderReference>
<orderDate>2004-08-15</orderDate>
<orderingSystem>WEB</orderingSystem>
<country>US</country>
<distributionChannel>A</distributionChannel>
<headerReturnCode/>
</header>
<spkSegmentList>
<orderItemReference>102</orderItemReference>
<spkPartNumber>69P9921</spkPartNumber>
<spkType>WMAINTOPT</spkType>
<spkQuantity>1</spkQuantity>
<hardwareQuantity>1</hardwareQuantity>
<spkReturnCode/>
<hardwareSegment>
<serialNumber>77X9182</serialNumber>
<hardwareIdentifier>8676M2X</hardwareIdentifier>
<hardwareReturnCode/>
</hardwareSegment>
</spkSegmentList>
</spkOrderDataList>
</ServicePacData:validationRequest>
|
列表 1 - 验证服务接收到的简单消息的样例,由针对将应用于某台现有计算机(通过其部件号和序列号确定)的单个 ServicePac® 的单个订单构成。验证服务会返回接收到的消息,并且用验证代码或错误代码对该消息进行注释。
调用组件可以提供自己的引用号,这样它就能够将请求与响应相关联。
协议独立性的另一个考虑事项是消息传递样式。在此项目中,将来对异步消息传递的需求已通过创建验证消息定义提出,该定义带有一个用于将请求与响应消息相关联的字段(目前未用),即使所有的当前使用都是同步的因而无需任何关联。
解决此类问题通常包括消息设计和应用程序设计。
业务灵活性
从根本上讲,ServicePac® 验证服务接受一张订单,然后返回指示该订单是否有效(如果无效,则还指示无效原因)的信息。 关键的是最大程度地减少为响应新业务需求而需进行更改时的重新设计、重新测试和性能影响。
很显然,在设计初始实施时了解可能的新需求是很有用的。
初始实施详细信息:
验证服务会抽取 ServicePac® 订单详细信息,该信息由以下内容构成:ServicePac® 类型、适用的硬件、ServicePac® 交付地点(国家或地区)、销售渠道以及客户数据。 然后,业务逻辑会参照一组由
ServicePac® 业务提供的声明性语句对订单信息进行测试。 这组必须应用于提供的任何订单的测试,取决于订单详细信息。某些测试需要访问只能从远程系统上获取的其他数据。
验证订单时需要三种类型的数据:此应用程序拥有的参考数据、其他系统拥有的已高速缓存的参考数据,以及每次验证订单时必须从其他系统上获取的实时数据。
此应用程序拥有的参考数据可通过构建为此应用程序一部分的伙伴服务访问。 需要访问此应用程序所拥有参考数据的其他应用程序也可以使用该服务。
其他应用程序拥有的参考数据则是通过访问构建为此应用程序一部分的伙伴服务来提供。 在可能时,伙伴服务会高速缓存从其他应用程序获取的数据,以便最大限度地减少网络访问次数。
通过在伙伴服务内放置高速缓存策略,就能够随时间变化、根据需要进行变更,而不必变更该应用程序的其他部分。
只需要在验证请求的生存期中存储的数据和中间结果被存放在 BPEL 变量中。 使用 BPEL 变量节省了由于对伙伴服务进行可避免的访问而带来的开销,因此可以提高整体性能。
图 2 - 以工作流驱动的业务逻辑实施的拓扑视图,它用于选择必须执行哪些计算密集型测试或数据密集型测试才能验证提供的订单。 所有需要验证订单的订单输入系统均使用相同的服务接口。
现在我们研究那些可通过业务讨论和观察历史趋势预见的新需求的性质。
随着 ServicePac® 业务的拓展,为 ServicePac® 验证创建了新的业务测试;但是现有的测试应该不会改变。 验证新产品需要评估现有测试和可能的新测试的新分组。
这组需求与工作流驱动的系统非常匹配,在此系统中,工作流用于将每个产品类型所需的多组测试结合在一起。 开发的计算密集型测试或数据密集型测试的灵活性可能较低,但是可向中央工作流引擎提供更高效的技术和显现为伙伴服务,如图 2 中所示。
当有新的业务产品添加到验证系统中时,将修改工作流本身以访问现有的伙伴服务(并可以添加支持此新产品所需的新伙伴服务)。
假定伙伴服务已在开始时适当地分段,则此体系结构展现了非常吸引人的附加模式,在这种模式中,新的需求将无需对先前已实施的功能进行大量的重新测试或重新译码。
可伸缩性
由于 BPEL 应用程序部署在一个成熟的中间件堆栈之上,该堆栈将集群提供为一个配置选项,可使 ServicePac® 验证项目通过按需要添加新硬件来轻松扩展规模的很直接的方法进行移动。
当然,从工作流引擎调用伙伴服务的总体系结构非常适合集群模型。
作为一个设计点,此服务是幂等的,因为对此服务的调用没有调用者可检测到的副作用。 因此,如果服务调用返回错误或未能完成,服务使用者不需要执行任何错误恢复操作。
实际上,服务使用者可以随时安全地重试调用。实际上,伙伴服务也是幂等的,这显著地简化了与使用群集缩放流程相关的因素,因为错误恢复比较简单且故障后的恢复和重新启动是直接的。
此外,由于每个迭代都是原子迭代,所以无需“调用者亲缘关系”,并且不存在与处理请求相关、特定于调用者的高速缓存。
工作流和 BPEL 的应用程序
BPEL4WS(Business Process Execution Language for Web Services,用于 Web Service 的业务流程执行语言)是一种语言和编程模型,它是专为执行基于工作流的业务逻辑(涉及
Web service 的编排)而设计的。BPEL 是一个开放式标准,适用于许多编写工具和运行时的供应商实施。
能够通过流程示意图描述 ServicePac® 业务流程,然后使用基于 BPEL4WS 的标准表示实施逻辑这一能力,将灵活性和隔离性很好地结合在一起以实施灵活的 ServicePac® 业务逻辑。
对于此项目,我们选择了 IBM WebSphere Application Developer Integration Edition(WSADIE)作为编写环境。 已开发的代码工件是用于运行在 IBM WebSphere®
Business Integration Server Foundation V5.1.1 运行时上,该运行时提供了一个业务逻辑执行引擎来随后执行工作流。此数据现在托管于 DB2(V8.1)服务器。
ServicePac® 验证所需的个别测试曾经实施为 Enterprise JavaBeans,尤其是在 WebSphere® Application Server EJB 容器中运行的无状态会话 bean。WSADIE 工具通过自动生成
WSDL 文件加快了将这些 EJB 集成为 Web service 的过程。 这样,这些个别测试既可以与 BPEL 流程部署在相同的容器中,也可以部署在其他服务器实例上的专用容器中。
图 3 展示了验证流程的图形 BPEL 编辑器视图。此工具支持折叠子流程并进行循环以简化整个工作流中各个片断详细信息的工作。
图 3 展示了完全展开的 BPEL 流程,当它出现在 WSADIE BPEL 创建和编辑工具中时,用于驱动 ServicePac® 验证服务。
当对 ServicePac® 验证工作流过程的早期实施进行修改以利用 BPEL 变量来存放中间结果(而不是对伙伴服务进行附加的调用)时,性能得到了显著的提升。 您可以在图 3
中看到此方法的示例,其中要对订单上的每个元素执行的测试列表存放在一个 BPEL 变量中。
此设计的优缺点概述
优点
|
缺点
|
1. 更快速且廉价地提供新产品
2. 降低了添加新的订购系统的成本
3. 可靠且全面的验证
4. 当订购系统更新后,可分阶段使用验证服务。
5. 新的验证逻辑只需要在一个位置实施和测试。
6. 验证逻辑由 ServicePac® 业务所拥有,并不分布在多个外部系统中。
|
1. 增加了运行时交叉组织依赖关系
2. 表现为额外网络等待时间的性能开销
3. 需要重新设计现有系统
4. 创建了一个新的集中式组件,它可能会成为多个应用程序的一个故障点。
|
在 ServicePac® 应用程序中,上面概括的优点提供了很大的价值,而缺点则都是可消除的。
由于允许个别调用者继续专有验证直至他们完成所安排的更新(涵盖许多问题),封装验证调用的数据这一附加编程工作并不会增加很大的工作量,它可包含在整个项目范围的调用应用程序中。
对于那些存在响应时间需求的联机服务,如果验证服务无法满足此需求,则可由调用者执行直接初步验证(inline preliminary validation),前提是调用者具有对验证服务的一个最终验证权。
此策略保留了调用应用程序的人为因素,同时还保持了整个 ServicePac® 订购流程的完整性。对于某些没有内部 Web service 协议功能的旧系统,构建了一个转换器,它负责接受专用协议,然后转换为 Web Service
调用(在此项目中为某个调用者构建了特定于 Web Service 适配器供应商的文档)。 服务健壮性测试和证明减轻了对验证服务引发的性能瓶颈的担忧。 通过使用集群技术,验证服务的吞吐量在需要提高时可非常迅速地增加。
最后,在所有因素相同的情况下,将验证逻辑集中到一个单独的实施中意味着原本用于部署和测试多个独立实施的资金现在可用于测试和部署一个单独的实施,我们认为这足以抵消与附加的单故障点相关的所有问题(许多异构订单输入系统具有该问题)。
最终,能够掌握验证需求及其实施、迅速推出新的产品、在订购流程开始时就确保订单验证的正确性和一致性的企业,就有能力考虑寻找新的机遇,而这些机遇在先前的技术条件下是无法实现或代价极其高昂的。
|