|
|||
|
作者:Jürgen Kress、Berthold Maier、Hajo Normann、Danilo Schmeidel、Guido Schmutz、Bernd Trops、Clemens Utschig-Utschig、Torsten Winterberg
行业 SOA 文章系列的一部分
2013 年 6 月
服务必须满足不同的架构和治理要求,其相关性由服务的重用方式来决定。布局和结构显著影响服务的分析和设计,继而决定了粒度级别。对服务进行分类可以更轻松地根据服务在过程环境中的使用情况来安排服务,这有助于防止不必要的麻烦。
没有经过分类的 SOA 架构迅速成为缺乏明确职责分工的“适配器”SOA。这些架构中业务流程的编排中穿插的技术服务调用可能导致不负责任的调用序列。
为了应对这些挑战,制定了一个 SOA 专业人士可用来描述不同类型服务的词汇表。在本文中,我们探讨 SOA 服务分类的各种可能性,然后介绍项目中已成功实现的各种服务类别。图 1 中的 SOA 服务分类矩阵将介绍的概念置于相应的上下文中。
公共服务
|
|
类别 | 外部视图 | 内部视图 | 调用 |
---|---|---|---|---|---|
业务流程服务 (BPS) |
|
可执行的业务流程 |
|
||
业务活动服务 (BAS) |
|
|
|
||
业务实体服务 (BES) |
|
|
|
||
业务规则服务 (BRS) |
|
|
|
||
实用工具服务 |
|
||||
私有服务 |
|
公共服务是用私有服务实现的。私有服务是公共服务的一个子集,经常由现有应用程序公开。对于公共服务,使用何种语言或应用程序实现并不重要。重要的是实现其接口描述的标准化。 私有服务与本地生命周期治理关系不大。 示例:Right-click-Java_Service、Controller-EJB、Siebel_Customer_Service |
图 1 — SOA 服务分类矩阵
首先介绍最适用于功能驱动的服务的服务类别。这些功能驱动的服务或“公共业务服务”通常发布在注册表(如 UDDI)中。然后讨论可以借助“私有服务”实现这些公共服务的不同方式,并探讨其他一些有用的类别。
业务流程服务 (BPS) 由业务流程的纯功能方面组成。这种类型的服务基于使用 BPMN 等语言或事件驱动的流程链 (EPC) 编写的流程模型,之后被转换成不同形式的可执行流程(如 BPEL 或 BPMN 2.0)并用于编排纯功能性服务。
换句话说,在功能端决定功能。设计人员无需再修改结构,因为他们现在能够调整自动或手动生成的流程框架。设计人员还可以用引擎中执行所需的技术细节增强结构。
为清晰起见,业务流程步骤和调用的服务应将任何更深层次的功能或技术细节(如转换)外包成不同的数据方言。组织通常将业务流程安排成层次结构,以便管理流程复杂性。BPS 通常是长期运行的,这与用例控制器不同,并且经常通过工作流功能结合了用户交互。
为了实现 BPM 承诺的松散耦合与灵活性,在流程设计过程中,至关重要的是使用功能术语仅描述流程操作而不描述具体执行方式。流程步骤的实现中涵盖了“具体方式”,可以有多种备选方案。BPS 重点关注功能方面。技术方面(如出入规范模型的数据转换)应外包给集成逻辑,这样 BPS 可以专心处理规范服务数据模型定义的数据。流程的更改应在业务模型中进行,应尽可能密切地维护业务模型与更技术性实现之间的联系。
业务活动服务 (BAS) 对应于功能上相关的业务事件,且封装了上下文特定的控制器逻辑。BAS 的上下文可以是业务流程的流程步骤或应用程序的用例控制器。BAS 处理更通用的基本服务,如业务实体服务 (BES) 和业务规则服务 (BRS)。但作为 BPM 项目的一部分,BAS 也可以调用业务流程服务 (BPS)。这确保了将每个流程步骤映射到一个 BAS,其实现可能包括从简单服务调用到复杂流程的任何内容。
业务活动服务的设计通常包括一个组合服务,该组合服务调用多个服务,通常是 BES 或另一个 BAS。. BAS 还包括一个包装器或功能扩展,使用上下文特定的逻辑(通常为一组业务规则)增强服务(通常为通用 BES)。
非上下文特定的业务逻辑应与管理相关数据的 BES 关联。这一决策取决于它是否是上下文特定的,意味着它是针对特定用例 (BAS) 设计的,而不是针对通用目的 (BES)。
BAS 通常在 ESB 中创建,所需数据类型之间基于 XSLT 的映射正是在 ESB 中组织的。BPEL 用于编排更复杂的场景,而 ESB 用于路由或分配 BPEL 流程。
以描述活动的谓词开头,然后是谓词作用的名词,最后是类别缩写“BAS”。
在以下各节中,每个示例中圆括号中包含的实现路径划分为“私有服务”类。
业务实体服务 (BES) 将逻辑业务实体相关的数据和功能(如客户或合同)封装在整个组织或特定于某个域、子域或部门的特定上下文中。BES 是实体级别的核心服务,其耦合尽可能松散。项目中经常讨论的重要定义包括 BES 始终封装实体的事实,意味着“Contract”等组合实体为 BAS。
尽管与包含复杂逻辑的 BES 相比,许多 SOA 架构师喜欢使用 BAS,以便绕过复杂性,但我们还是更喜欢用 BES。应基于外部可感知的接口来定义服务,而不是基于其实现。此决定考虑到了服务协议不仅构成交换数据,而且还构成运行时行为的事实。如果 BES 是按“无状态和短期”分类法定义的,这将导致长期操作从 BES 迁移到 BAS。
以从功能上描述实体的名词打头,后面跟分类缩写“BES”。
CustomerBES
业务实体服务经常有一些其行为由实体的当前状态决定的操作。根据情况的不同,将上下文特定的功能外包到可以与静态甚至更基本的实体一起工作的各个 BAS 可能很有用。
例如,考虑一个上下文特定的“CustomerUponSaleBAS”,它为通用“CustomerBES”执行工作。这正是 BAS 作为上下文 facade 的本性的形成方式。
实体服务的数据和功能基于一个或多个来源,这些来源以应用程序或单个组件的形式出现。与实体紧密联系且因此与上下文关系不强的业务逻辑可与实体服务合并。拥有各种操作的非常复杂的实体本身可以细分为独立、一致的实体服务。一致性的条件是必不可少的,因为每个实体中的上下文、数据和功能是一个整体。
MDM 需要与 BES 封装的实体关联。“写入”等事务性操作可能导致 BES 运行时间延长,尤其是在写入操作需要用户交互的情况下。替代方法是将 BES 操作提升到业务流程级别。
由于 BES 的主要功能之一是执行搜索,所以有可能将调用之上的筛选器外包到 BES。BES 将返回一个完整的业务对象,使用搜索条件重新对其进行了筛选,可提供完全符合特定上下文需要的数据。另一个替代方法是让 BES 为每个搜索上下文提供大量精确定义的搜索/查找操作。不过,这两种方法都将超出合约范围,增加治理所需的工作量,频繁更改会加重服务生命周期的负担。
作为过载的解决方案,推荐的设计是让 BES 定义一个通用查找器方法,以 XML 格式公开类型。调用方法时返回的字段可定义为“find criteria”对象,可在运行时删除。
业务规则服务封装决策树中的决策(如“If 'Good Customer,' then...”)以及经常用作一个功能的先决条件的验证。验证可确保数据在需要时处于正确的状态且特定于上下文,如“客户数据正确”。
使用有意义的名称表示规则的结果,后面跟缩写“BRS”。
“calculateWhetherGoodCustomerBPS”
按照 SOA 定义松散耦合和“分别考虑”的概念必须在更高的抽象级别区分“公共”和“私有”服务,以保持服务合同与实现之间的区分。
这种区分明确了如何将现有功能合并到公共、可重用且松散耦合的服务中。面向对象的编程区分“私有”和“公共”的概念来定义对象和方法的可见性和作用域。私有方法或属性是与实现有关的细节,对外不可见,而公共方法是可以访问也是通常使用的接口。
公共服务构造在功能接口上,作为实现 facade。实现可以是任意数量的私有服务。因此公共服务完全由客户的需求和功能感知驱动。它们还严格地遵循与实现无关的原则,因为它们的接口只处理外部可见的行为,这样才不会公开实现细节。在私有和实用工具服务级别从内部访问数据库的 BES 可以提供功能数据,无需向外部传播任何技术细节,如 DB 密钥。
公共服务旨在允许服务重用,这要求服务尽可能少地特定于上下文或状态。这样就支持最大范围的上下文中重用,尽管每种服务类型对应于不同的上下文依赖程度。因此,业务活动服务明显比业务实体服务更特定于上下文。公共服务只以规范数据格式交换数据,在 (UDDI) 服务注册表中可以归为“公共服务”类别。
这些服务还以连续集合的形式为操作提供完整的功能,逻辑上与各自概念一致。根据服务分类法,公共服务分为业务流程服务 (BPS)、业务活动服务 (BAS)、业务实体服务 (BES) 或业务规则服务 (BRS)。
例如,检查客户信誉度的公共服务操作接收客户数据,用来验证客户是否值得信任。调用服务的模块应不能查看其实现方法,无论是遵循计算申请人属性的复杂工作流还是使用第三方信用评估服务。此方法的好处是可以更换实现形式而不影响客户,只要 WSDL 保持稳定。
大部分上下文特定的逻辑(如用例控制器逻辑和数据格式映射)不应存储在公共服务中。如果违反此规则,服务层将对所有特定上下文有较高的依赖度,大大提高公共服务的重用难度。前端控制器准确封装了这些方面并调用通用 BAS。
新上下文(如新 Web 门户)导致的对服务合同的扩展和更改应使用公共服务通过管理服务生命周期的严格治理制度执行。角色和权利的逻辑应保留在服务、前端和后端可以访问的中央授权组件中。
公共服务通常使用 WSDL 定义,其中包含使用 XML 模式定义的每个操作的类型。但是有些使用者使用的是其他语言,如逗号分隔值 (CSV),甚至是 Cobol。翻译成这些语言的作业可能需要外包给特殊适配器,在公共服务之上进行转换,因为服务合同不能过载。但这种选择将会使架构再次变得臃肿。
另一个解决方案是让 ESB 支持与这些语言适当绑定,这样与 WSDL 和关联 XML 模式的服务合同可保持原样。定义的操作可以与 CSV、Cobol 或 ESB 中配置的其他语言的绑定关联。
一旦创建通用语言,即可将服务归入每个类别,便于交流。区分公共和私有服务可简化服务的创建,这些服务完全由功能驱动,可以合在一起构建模块化的服务库。关注外部可见的行为本身就会导致松散耦合,可以取代服务的实现元素而不影响使用者。
实现这些步骤意味着最终可以实现灵活的可执行业务流程,因为 BPS、BAS、BES 和 BRS 类别有助于组织服务。服务调用成为元概念的一部分,有助于更好地理解服务功能。可以轻松读取服务调用序列,例如,当“CarRentalBPS”调用“calculateRentalFeeBAS”时。然后此服务使用“returnCustomerConditionsBES”和“returnBillingAddressBES”,它们分别实现来自“CarRentalSystem”和“InvoiceSystem”的功能。
可以为已正确注册的公共业务服务生成评估和报告,其中包括每种类型的服务的数量和可重用性信息。这些报告还有助于简化计费流程,因为可以基于报告的服务使用情况收费。
实现团队可以通过遵循明确定义的服务分类系统高效地设计可重用服务。服务分类是迈向集成治理的第一步,应当内嵌在项目设计指导原则中。尽管并非每个 SOA 项目都需要 BPS、BAS 或 BES,但区分公共服务和私有服务还是非常重要。
D. Krafzig、K. Banke 和 D. Slama。《Enterprise SOA:Service-Oriented Architecture Best Practices》。多伦多:Prentice Hall,2004。