低起步,高成长

作者:Edwin Biemond、Ronald van Luttikhuizen 和 Demed L'Her

一系列务实的最佳实践,用于部署可随业务需求的增长不断扩充的简单、可靠的 SOA 规模。

2012 年 1 月发布

目录

管理考虑事项
贵组织是否有中间件管理员?
部署最佳实践
脚本编写与手动配置
搜索实例 — 组合传感器和 bpel:exec
负面测试 — 绝对必要
其他管理考虑事项

基础架构考虑事项
构建集群 — 即使只有一个节点
有关域的考虑
硬件、数据库和操作系统选择
负载测试
清除和备份 — 如何应对数据库增长?

开发考虑事项
在 MDS 中集中存储构件
规范模型 — 简单化
服务设计准则和命名约定
将常用 Oracle SOA Suite API 包装在更简单的自定义 API 中
构建敏捷性 — 使用 DVM 和业务规则
故障处理
单元测试

架构考虑事项
服务分类
服务粒度
通过事件实现分离
版本控制
注册表和信息库

总结

参考资料

下载
download-icon13-1Oracle 融合中间件


理想情况下,大家都希望以非常系统和战略的方式开始构建面向服务的架构 (SOA):聘请开发人员和架构师团队、调查企业中的现有资产、提出全面的企业级架构并从中得出相应的软硬件需求。可以想像,这种全面的方法需要大量时间、资源和前期规划,而这不是大家都办得到的。我们经常看到一些公司希望以更灵活、更战术性的方式部署集成基础架构,比如说,他们只以互连两个应用程序为目标。同时,他们希望借此机会奠定最终可以成长并支持更全面 SOA 的基础。好消息是这两个目标并非不可调和的。

本文重点介绍几个简单而务实的最佳实践,以帮助大家为将来构建坚实的基础。这些实践跨多个领域:管理、基础架构、开发和架构。

管理考虑事项

您可能会觉得有些奇怪,既然 SOA 工作一般是从开发或架构方面开始着手进行,为何本文首先提到管理方面的考虑事项?遗憾的是,运营团队通常太少或太晚介入 SOA 项目。开发人员经常在最后一刻才将项目甩到运营团队手上,要想满足最终期限是不现实的。通常,这会导致大幅修改项目时间表,或者在不具备所要求的基础架构的情况下匆忙将项目投入运营,使经年累月小心翼翼的开发工作暴露于风险之下。

具体的建议是,从一开始就至少让一位系统管理员加入您的虚拟团队。确保运营团队接受技术培训,且该团队介入实际运营的规模调整、安全性、可管理性和验收标准方面的工作。

记住,最终您的管理团队将按照您对端到端项目时间表的遵守情况以及应用程序的稳定性和性能(而不是内部组合与 BPEL 设计是否优美)来衡量您是否成功。任何 SOA 项目的成功都与一支有能力、有意志的运营团队分不开。

贵组织是否有中间件管理员?

不同组织的管理员的技能和职责各不相同。管理诸如 Oracle SOA Suite 和 Oracle Service Bus (OSB) 之类的中间件组件完全不同于管理数据库、网络或文件系统。请确保贵组织聘请了解其中间件的管理员,即便是小型易于管理的环境。由于 SOA 组件在 Oracle WebLogic Server 中运行并使用 Oracle 数据库,因此应用服务器管理员或数据库管理员通常是最终接管 SOA 管理职责的人。理想情况下,生产环境的管理不应留给开发人员,这是出于技能、重要性和责任制的考虑。

部署最佳实践

部署 SOA 组合应用程序有三种可选的方法:

  • 使用集成开发环境即 IDE (Oracle JDeveloper);
  • 使用管理控制台 (Oracle Enterprise Manager);
  • 使用脚本(WebLogic Scripting Tool 和 ANT)。

管理员在其环境中很少有(或需要)IDE,这就使第一种部署方法仅限于开发人员使用。在测试、验收和生产环境中,管理员可以使用 Oracle Enterprise Manager 或 Ant 和 WebLogic Scripting Tool (WLST) 脚本。尽管通过 Oracle Enterprise Manager 进行部署在仅处理少数组合时可能是可行的,但首选方法始终应是编写脚本。通过部署对话框一步一步地进行可能很快就使人厌倦,但更要紧的是,它增加了出现人为错误(错误的分区、错误的配置计划等)的机率。请在项目早期开始为构建、部署、测试和启动服务组件架构 (SCA) 组合和 Metadata Services (MDS) 信息库创建 Ant 和 WLST 脚本。Oracle JDeveloper 的 integration 目录和 Oracle SOA Suite 主目录的 bin 目录包含可用于此目的的自定义 (SCA) Ant 任务。WLST 也有针对 SCA 组合的特定命令。有关详细信息,请参见针对 Oracle SOA Suite 和 Oracle Business Process Management Suite 的 Oracle 融合中间件管理员指南 [5]

SOA 组合依赖于许多其他服务和资产,如数据库、Web 服务、Enterprise JavaBeans (EJB) 或消息传递提供程序(如 Advance Queuing (AQ) 或 Java 消息服务 (JMS))。随着组合从一个环境流向另一个环境(开发、测试、验收和生产 — DTAP),必须同步更新对这些依赖项的引用。在测试环境和生产环境中,从特定组合调用的 Web 服务可能运行于不同端口上。最佳实践是使用随取随用的 Oracle SOA Suite 配置计划来捕获所有环境特定的信息,如 Web 服务端点、Java EE 连接器架构 (JCA) 设置和 Oracle Web Services Manager (OWSM) 策略),将这些信息保存在一个单独的配置文件中,而不是将其硬编码到组合中。Oracle WebLogic 还支持 WebLogic Server 部署计划,但这更多地是针对 Java 2 Platform Enterprise Edition (J2EE) 和 Oracle WebLogic 部署描述文件,不能用于 SOA 组合。

另一项最佳实践是避免为每个环境中的每个组合创建一个单独的配置计划。例如,假设您部署的 SOA 组合的数量增加到 145 个(此数字并非不切实际)。然后您就将有 (145 * 4 =) 580 个单独的配置计划需要维护!更好的办法是将这些计划整合成每个环境一个配置计划。随着这些文件慢慢增大到难以维护的程度,您可能需要开始寻找某种更精细的办法,例如,让每个环境中的每个 SOA 分区有一个计划。同一计划将用于将所有 SOA 组合部署到该特定环境。这最终将提高项目之间的一致性,大大减少出错的几率。


start-small-fig01
图 1:利用一个配置计划应对环境差异的典型部署方案

编写脚本与手动配置

SOA 环境通常由不同组件和中介(如 OSB、Oracle SOA Suite、数据库和 Java/JEE 应用程序)组成。它们各自的配置并非集中式的,而是分散到各种文件和信息库中。这些配置可以是安全设置(LDAP、WS-Security 标头)、消息传递设置(JMS、AQ)、数据库设置 (JDBC)、日志设置、端点设置 (WSDL URL) 等。如果您手动配置每个系统,配置工作很快就会变得难以跟踪了。此外,当您扩大 SOA 规模,需要提供新的环境时,您将希望它们尽可能接近于现有环境,以便进行维护和故障排除;没有什么比环境特定的问题更令人沮丧和耗时了!

解决一致性问题的办法是编写脚本:从一开始就要将尽可能多的配置任务编写成脚本。尽管这需要一些前期投入,但会确保您的供应过程保持一致,并且这会带来所有预料之中的好处:更轻松的维护和故障排除、更快的周转时间、更简单的更新。同时,配置还应记录在众所周知的中央位置,如团队 wiki,以便所有利益相关方可以随时从该位置获得这些配置。

下面是应考虑编写脚本的具体任务示例:

  • 使用 LDIF 脚本在 LDAP 信息库中创建和管理用户、组和角色。
  • 使用 WLST 创建和配置 WebLogic 域。
  • 使用 WLST 或基于域模板的配置创建和配置 JMS 和 JDBC 构件。
  • 使用静默安装和响应文件安装所有软件 [9]。这适用于部署新环境以及向现有集群添加新节点。

WLST 是完成这些任务的极佳工具。有关 WLST 的更多信息,可在 Oracle 融合中间件 Oracle WebLogic Scripting Tool [6] 中找到。

搜索实例 — 组合传感器和 bpel:exec

有时,业务用户或管理员希望了解进入系统的特定请求发生了什么,或者希望得到有关特定流程的状态信息。在低容量环境(几个 SOA 组合和几十个实例)中回答这些问题可能相当轻松。当您有几十个或上百个 SOA 组合以及成千上万甚至数百万个实例时,这样的任务就变得非常困难了。如果业务用户知道故障或请求的确切日期,将很有帮助。但通常您希望能够使用特定数据(如发票编号或员工姓名)来找到信息。

组合传感器是一种方便的、随取随用的机制,允许基于有效负载中包含的特定字段搜索特定实例。可将组合传感器看作数据库索引。

与数据库索引一样,不要弄过头了,您应该只添加必要的组合传感器。要逐个组合地对需求进行评估。对于频繁调用的同步及生命周期很短的组合,应考虑关闭审计线索,只在出错时才重新调用该服务。在这些情况下,搜索特定实例并没有什么更多的用处,反而徒增开销。而长期运行的流程则非常适合使用组合传感器。

附带提一句,可以使用 bpel:exec 活动通过 BPEL 组件设置组合实例的标题。此类实例名称也可用于定位实例。但由于以下种种原因,用这种方式设置实例标题可能有点危险:在编译和部署时不会验证 bpel:exec 活动内部的 XPath 表达式,您需要对它们进行彻底测试。更改实例标题所基于的命名空间或元素名称可能导致运行时故障,最重要的是,这种嵌入式代码难以调试和管理。

负面测试 — 绝对必要

以下可能是本文中最重要的一条建议:确保对生产中可能遇到的问题进行广泛的测试。90% 的情况下,随着最终期限的临近,人们忙于对设计进行润色和反复推敲,挤压了留给测试的时间。因此要抵制诱惑,将这些锦上添花的内容留到下一里程碑去完成,因为使您的项目无懈可击要重要得多!至少您应针对以下情况测试和设计恢复过程:

  • 基础架构数据库关闭(或网络故障);
  • 目标系统关闭(或网络故障);
  • 目标系统返回非预期数据(如应用程序级错误消息)。

重要的是要了解系统在上述情况下会如何反应,以及如何对这些情况进行补救。按照墨菲定律,这些问题通常发生在您外出度假的时候,因此请确保记录:

  • 症状
  • 说明
  • 恢复过程(按何种顺序停止和重新启动服务;是否可以按原样重新提交实例或者是否需要先执行任何补偿逻辑等)。

这可以保证您睡一个安稳觉并且保证业务不会中断。要记录这些重要信息,wiki 是一个完全可接受的地方,只要确保及时更新并且管理员人员随时可以访问。理想情况下,还应编写补救过程的脚本(Ant 或 WLST),但记录是绝对最低要求。

其他管理考虑事项

EIS:企业信息系统
此术语表示系统(集成点),包括消息传递中间件(AQ、JMS、MQSeries)、打包的应用程序 (EBS) 以及其他系统和平台(如 FTP 服务器、文件系统、邮件服务器)。

使用 OSB 或 Oracle SOA Suite 中众多 JCA 资源适配器中的一个时,您需要创建一个资源适配器计划,其中包含该适配器的所有 EIS 连接。此计划(XML 文件)将在管理服务器上的文件夹中创建。还需要使其对每台托管服务器可用。除了在每台本地托管服务器上创建副本,还可以使用共享存储,如 NFS 共享。

Oracle SOA Suite 11g 包含 SOA 分区(有些类似于 Oracle SOA Suite 10g 中的“BPEL 域”,不过没有调优部分)。从架构和管理角度来看,分区很有用。分区是一种将组合划分为各种组的机制,非常类似于以文件夹的形式组织文件。如何对组合进行分类完全取决于您,可以根据功能、业务领域等进行分类。分区还有其他用处,它们让您可以对分区内包含的所有组合执行各种任务,比如批量激活和部署。您应考虑使用分区来简化管理。

基础架构考虑事项

在基础架构方面,您的总体目标应该是构建一个无需重新设计整个系统就可以轻松扩展的基础系统(以处理更多负载或提升故障切换功能)。强烈建议您抽时间阅读和熟悉内容全面的 Oracle 企业部署指南 [2]Oracle 融合中间件高可用性指南 [3]。现在,下面简要列出了一些必须考虑的事项。

构建集群 — 即使只有一个节点

尽管当前的需求可能不要求消息的完全高可用性 (HA) 或高吞吐能力,但将来情况可能会发生变化。如果您部署成功(对此我们毫不怀疑!),将很快发现有更多的服务需求。那时您将需要确保可以横向扩展以处理负载并且可能需要实现非功能性要求,如高可用性。

要实现 HA 和更高的吞吐能力,有两个可选的方法:

  1. 无共享存储的 WebLogic 集群。您有多台服务器的事实意味着即使一台服务器停机,您的运营仍将继续(尽管容量降低)。但此配置并未完全防止消息丢失。如果一台服务器出现故障,您必须手动重新启动它(首先处理完诸如硬件故障等可能导致该服务器停机的事件之后)。当服务器重新启动时,它会读取所有事务日志和 JMS 文件持久性文件来尝试进行恢复。如果恢复失败(比如,由于磁盘损坏),您最终可能会丢失一些运行中的请求/消息。您还需要使域在所有服务器上保持同步:例如,您的资源适配器计划应存放在每台服务器上。
  2. 带共享存储的 WebLogic 集群在这种情况下,所有托管服务器都将事务日志和 JMS 文件持久性文件存储在共享存储上。通常您会在此启用服务器迁移选项。服务器迁移允许 WebLogic Node Manager 将托管服务器从刚刚发生故障的计算机迁移到新的计算机上(这需要大约一分钟),为该计算机添加虚拟 IP,然后启动托管服务器。之后,迁移的托管服务器将使用共享存储中的事务日志和 JMS 文件持久性文件恢复操作。这是确保服务不中断并且事务不丢失的最佳配置。

一旦 SOA 平台上有了更多的服务,并且这些服务的使用更加频繁,HA 将不再是一个可有可无的功能:它将成为一个绝对必需的功能。

需要注意的是,没有什么捷径能使一台服务器的安装配置扩展为集群,您必须重新安装。正是由于这个原因,始终从集群开始至关重要。如果您没有足够的硬件支持一个 2 节点集群,甚至可以构建一个单计算机集群;这也可以正常工作,并确保您在将来能够扩展。

更多的几点提示:

  • 为所有组件使用单独的 IP 地址。尽管可以只用一个 IP 地址和不同的端口号来安装 WebLogic 管理服务器、Node Manager 和托管服务器,但这在生产环境中并不是一个好主意。应为每个组件指定自己的 IP(或者在服务器迁移中为 VIP)并使用标准端口。Node Manager 可以使用计算机 IP,所有 WebLogic Server 有自己的 IP(您可以为单个网卡添加额外的 IP)。这样就可以在一台计算机上运行集群,并可以稍后将管理服务器或集群中的某一个节点移到另一台计算机(从 NIC 删除相应 IP 并将其添加到新的计算机并启动)。
  • 使用 JVM 监视工具。利用诸如 JRockit Mission Control 之类的垃圾回收工具可帮助您查明是否需要为 JVM 分配更多内存。您还能够调优或检测 Oracle SOA Suite 集群中的问题。
  • 利用 WebLogic 通道。通道允许您分离集群流量(Oracle Coherence、同步、Node Manager 流量、管理服务器流量)与生产流量。通过使用不同的段和交换机,可以减少生产网络的大流量负载对集群完整性产生负面影响或导致“裂脑”状况的机会。
  • 负载平衡器。在 Oracle SOA Suite 集群中使用负载平衡器,以便在服务之间分配流量并检测集群中服务器停机的情况。可以使用硬件负载平衡器,也可以使用软件负载平衡器(如 Oracle HTTP Server)。为定义 EJB 和 JMS 端点,可以将所有托管 WebLogic Server URL 添加到 T3 URL,以实现负载平衡。

有关域的考虑

在此假定您已经熟悉 WebLogic Server 域的概念。域的拓扑结构形式多样,在最简单的情况下,管理服务器和托管服务器位于同一台服务器上,无 Node Manager;在最复杂的情况下,管理服务器与托管服务器分离,有 Node Manager,使用多个 WLS 域将应用程序和服务划分到各个功能域,等等。没有一种“通用”的域拓扑结构;各个项目之间存在太多的可变因素:可用硬件、功能要求等。尽管如此,在这一方面我们仍然可以给您几点提示和指导原则:

  • 使用 Node Manager。Node Manager 是轻型的,非常便于管理您的服务器(如停止和启动),而且对于服务器迁移必不可少。
  • 不要合并管理服务器和托管服务器。 尽管开发人员安装允许您将管理服务器和托管服务器合并在一个 WebLogic 实例中,但不应在生产环境中选用这种拓扑结构。但如果需要,这两个 WebLogic 实例可共存于同一台计算机上。
  • 将软件和服务部署到托管服务器。不要将软件和服务部署到管理服务器。
  • 利用域对具有不同生命周期或功能明显不同的环境进行分区。尽管您应避免使用过多域(这会引入管理开销),但应记住给定域内的所有服务器需要同步进行管理、升级和调优。由于这些原因,您应使用不同的域来部署不同系列的应用程序(例如,一个域用于身份和访问管理,一个域用于 JEE/Java 应用程序,另一个域用于 SOA)、不同升级周期的应用程序(域中所有服务器需要使用同一 WebLogic Server 版本)、功能明显不同可能需要不同调优的应用程序(如,同步与异步)或不同组织管理的应用程序(如,内部开发与合作伙伴提供的开发以及现成的商业应用程序)。
  • 将性能最好的硬件用于托管服务器。如果您有异构硬件,应将最快的计算机留给托管服务器(实际处理请求的服务器)。管理服务器用于配置、部署、监视等。因此,其使用较不频繁,常常对性能要求不高。如果您频繁使用 Oracle Enterprise Manager,就需要另当别论了,这种情况下,该软件也可能需要大量资源,尤其是在高容量环境中。注意,我们谈论的是性能,不是可靠性。显然,管理服务器应部署在非常可靠的硬件上。您还可能会考虑将管理服务器移到与托管服务器相同的计算机上,以节约硬件资源。

有关域拓扑结构及其选择的深入信息,建议您阅读 Oracle 企业部署指南 (EDG) [2]。记住,EDG 指南展示了一个非常全面的部署架构,其复杂程度可能超出了您的实际需要。

硬件、数据库和操作系统选择

运行 Oracle SOA Suite 的最佳操作系统通常是您最有经验的操作系统:从 Windows 到 Linux 和 Solaris。在本文撰写之时,运行 SOA 的典型服务器是 64 位四核计算机,带 16 至 32 GB 的 RAM。Linux、Solaris 和 Windows 是我们最常遇到的操作系统。

数据库是 Oracle SOA Suite 的一项重要要求,更具体地,对于需要持久保存状态的组件(如 BPEL)来说非常重要。(另一方面,Oracle Service Bus 很少用到数据库,除非您使用报表和 OWSM 策略。)尽管 Oracle SOA Suite 支持各种数据库作为其基础架构,且可通过适配器与更多数据库集成,但强烈建议部署在 Oracle 数据库上。这是目前采用得最多的方案,Oracle SOA Suite 包含许多针对该平台的优化,如支持分区等。此外,在数据库服务器上使用 RMAN 和 Data Guard 始终是个好主意。

负载测试

设法在验收环境中复制预期的生产负载(应是生产环境的完全克隆)。这将确保系统不仅可以满足预期的业务要求,而且也是培训管理员的最佳地方。

在负载测试期间,确保记录一些关键统计信息。例如,给定服务的平均和最大响应时间,或者给定调用应导致给定下游组合的 X 个实例化的事实。您还应监视测试期间数据库的增长,并使用这些结果推断生产环境中将需要的数据库大小。由于要脱水的数据量特定于您的组合,因此测试是进行此项评估的唯一可靠的方式。

清除和备份 — 如何应对数据库增长?

每次调用 SOA 组合时,就会将数据添加到数据库中的脱水存储中。这是持久保存状态的地方,对于事务性、审计等很关键。脱水存储的增长速度与 Oracle SOA Suite 正在处理的数据量直接相关。有一件事情是肯定的:到了某种程度您将必须进行清除。清除过程应及早测试,并作为验收标准的一部分;不要到实时运行并用光数据库空间之后才想起这件事!

清除是一个复杂的主题,不在本文讨论范围内。但这里告诉大家,主要有四种方法可用于从脱水存储中删除实例,下面按最简单到最高级的顺序列出:

  • Oracle Enterprise Manager Console
  • 循环清除
  • 并行清除
  • 分区

EM Console 方法主要用于逐个删除特定实例 — 它本质上并不是一种清除方法。高容量环境应认真考虑使用数据库分区,需要注意的是,此方法需要精心的前期规划(它将需要数据库级的分区许可以及对模式进行重新分区,因此避免在实际运行之后采用此策略)。低容量至中等容量环境可以定期(例如每 24 小时)使用循环清除或并行清除。

开发考虑事项

即使拥有最快的硬件、最好的基础架构、极棒的运营团队,软件编写得不好一样会限制性能。本节我们来看看设计时考虑事项,以确保 SOA 组合性能良好、可维护。

在 MDS 中集中存储构件

服务重用对于利用 SOA 的好处非常关键。为了使用给定服务,您的项目必须可以访问该服务的接口(通常由 WSDL 和 XSD 来定义)。最简单的方法是导入这些构件并将其保存在本地,即保存在项目中。但这最终将导致需要维护这些构件的许多副本,即每存在一个项目使用这些构件,就要维护一份这些构件的副本。只要服务的合约、接口或版本发生变化,每个使用它的项目将需要重新导入和重新部署关联的 WSDL 和 XSD。从长远来看,将这些共享资源存储在本地并不是一个很牢靠的办法:复制构件不仅会使管理和同步更复杂,而且会影响服务器上的整体内存使用率。Oracle Metadata Services (MDS) 是一个随 Oracle SOA Suite 现成安装的运行时信息库,可用于集中存储和共享可重用构件,如跨越多个组合的服务合约 (WSDL)、规范数据模型 (XSD) 和故障处理配置(故障策略和故障绑定)。组合和组件可以使用逻辑 URL(以 oramds:// 开头)引用 MDS 构件。

最佳实践是使用 MDS 保存这些构件的单一版本,在多个组合之间共享(而不是将其复制到每个组合)。这将避免不必要的重新部署、提高服务更改的速度、降低整体内存使用、帮助避免无效的组合并节省大量的构件维护时间。

本文档的后续各节将重点介绍 MDS 在各种特定目的下的用法。

规范模型 — 简单化

即使您开始只有少数几个服务,也有可能会遇到一些核心(业务)对象,这些对象将在您的组合和各种来来的项目中反复遇到。例如,如果要将客户门户连接到 CRM,您应花一些时间考虑客户对象应采取何种模式。您不必大费周章地为这第一个项目中将要使用的每个实体定义规范模型。对于较少使用的外围实体,依赖 1:1 映射是完全可以接受的。还要记住,使用规范模型将对性能产生一定影响:要从格式 A 转到格式 B,您将需要从 A 转换到规范然后从规范转换到 B,因此引入了额外的转换。但核心对象有一个规范模型很重要,认真进行一些规划可长期确保未来的重用和一致性:

  • 首先在简单初始项目的环境中草拟规范客户对象。考虑您要使用的命名空间并以复杂类型级别为限制。您可以使用特定大小或类型的基本元素制定模式并在复杂类型中重用。
  • MD 很适合存储规范模型(如前所述)。
  • 在整个方案中引入另一个系统(例如可能成为下一个集成项目一部分的系统)是验证初始选择的好办法。您的规范模型在此系统下能否正常工作?
  • 您不应只为规范化/去规范化就引入网络跳跃:如果已使用 OSB 进行服务虚拟化,这将是这些转换的最佳位置。否则还可以使用组合内的中介器执行转换。
  • 规范模型通常在组合与其他系统和服务(在 Oracle SOA Suite 之外实现)之间共享。当组合相互调用时,请考虑对组合使用本地模型。这样,规范模型中的变化不会破坏组合之间的集成。在集成和解调层(通常是 OSB,若其已部署)使用规范数据模型。

另一最佳实践是使服务接口定义尽可能保持简洁。不要整个传递组合所操作的所有业务实体,只传递这些实体的逻辑标识符。可以在组合内部使用这些标识符检索使用基本服务的业务实体。此机制称为“声明检查”模式。这会促进松耦合(因业务实体 (XSD) 中的更改不会改变服务接口),可以降低审计线索和脱水存储中有效负载的大小,并确保所操作的业务实体是最新的。如果需要,我们将检索实际数据,而不是在服务中拖延使用可能陈旧的实体。

合约优先、自下而上还是中间会合?

本文至此对 SOA 采用的是自下而上 的方法,这是一种有组织的、受集成项目驱动的方法,没有大量的前期规划。对于那些向外界公开的接口,考虑采用合约优先中间会合 的方法。有许多很好的文章和博客讨论了这些方法。[10]

当遵循自下而上的开发方法时(例如,通过公开由 JCA 适配器向导生成的 WSDL),您对某些属性(如命名、命名空间、操作等)基本没有控制。对于内部接口这样做可能不错,但对于需要长期生存的、逻辑的、自描述的(命名方式)且不经常更改的外部接口,这样做就不太理想了。当您以合约优先或中间会合方式开发服务时,可以控制 WSDL 和 XSD 构件的命名约定,且可以轻松为每个服务添加多个操作。以合约优先和中间会合方式进行开发还允许您引用规范数据模型而不是最后采用自动生成的模式。

下面是其他一些最佳实践:

  • 使用抽象 WSDL:合约优先式服务 WSDL 可以是所谓的“抽象 WSDL”,即它们只包含消息和端口类型,不包含实现细节(如绑定或服务)。将此 WSDL 放入 MDS 中并从中使用(引用)它可避免处理环境特定的对象,如具体端点。您可以在组合部署后通过 Oracle Enterprise Manager 下载具体的 WSDL(即实现)。将其重命名为 xxxImpl.wsdl 并添加到 MDS 中的抽象 WSDL 旁边。使用配置计划等将组合部署到特定环境时,此 WSDL 可以由其他引用该服务的组合使用。注意,您可能需要验证和修改来自下载的 WSDL 的 WSDL 和 XSD 导入。
  • 您无需公开自动生成的 WSDL:如果您已经创建了组合但对结果自动生成的 WSDL 不满意,请使用中介器从理想的(合约优先)WSDL 和 XSD 映射到自动生成的 WSDL 和 XSD。在这种情况下,中介器可帮助您采用中间会合的方法来协调合约优先与自下而上的方法。
  • 使用中介器保护核心逻辑不受外部更改的影响:直接调用并非自己拥有的外部服务时(与通过 Oracle Service Bus 等中间层进行调用对比),您可能希望使用中介器进行转换。这样,如果外部服务发生更改,您只需更新中介器,而不是 BPEL 或 BPM 组件内部的业务逻辑。对于组合中使用的“正式”规范数据模型和“本地”元素,可以使用同样的方法进行转换。
  • 使用 MDS 避免因依赖关系导致的启动问题:组合可能彼此引用。启动 Oracle SOA Suite 时,组合将逐个激活,对于激活顺序没有显式控制(例如,不像 EJB 之类的 WebLogic 部署)。在启动期间,需要解析组合引用;否则可能有组合无法启动。如果所引用的外部服务处于关闭状态,或者一个组合所引用的另一个组合在 Oracle SOA Suite 启动过程的稍后阶段才激活,就可能发生这样的情况。使用 MDS,您可以确保组合彼此独立,且与超出您控制范围的外部服务保持独立。组合将从 MDS 读取其他服务的 WSDL 和 XSD,而不是尝试检索其端点。因此,MDS 分离了服务,从而避免在 Oracle SOA Suite 启动时出现无效组合。[12]

服务设计准则和命名约定

每个软件开发人员都有自己的风格;每个行业都是这样的。一种风格并不一定比另一种更好,团队为了具备一定的多样性可以接纳某种不同的风格,只要这种风格不会导致根本性的不一致和代码难以管理。底线:每个开发团队应对基本编码约定达成一致。

其目标是随着 SOA 工作的进展,使新加入的开发人员尽可能顺利、快速地进入角色。编码风格的一致对此很有帮助,因为新的开发人员知道对他们的期望。这还可以帮助可能需要钻研代码或只是跟踪各种组合的审计线索的运营团队。

以下是 SOA 项目中风格的两个重要方面:a) 如何设计服务(哪些组件一起形成组合),以及 b) 组合、组件、服务和引用的命名约定。

建议您的编码约定至少应包括以下几个方面:

  • 语言约定:如果您在非英语国家,则需要在这一方面制定明确的指导原则。许多术语已经是英语的(如 BPEL 活动名称)。在编程中,您应一切都用英语还是应尽量使用本地语言(如变量名和活动名)?同样,没有一个通用的解决方案。但使用英语通常是安全的。要知道,运营团队(如果是全球性公司,则可能位于其他国家)会接触到一些内部的东西,如出现在审计线索中的变量名。有些时候外部资源(顾问、Oracle 支持部门等)也可能需要介入。
  • 组合、服务、引用和组件的命名约定:例如,是否应使用某种短标识符作为每个组合的前缀?
  • BPEL 和 BPM 组件和活动的命名约定:这一点尤为重要,因为如果执行的活动数量增长很多,可能很难发现长期运行的 BPEL 和 BPM 实例中所发生的情况。对作用域、顺序和其他活动进行合乎逻辑的命名可能帮助极大。
  • 组合传感器的命名约定:如果使用组合传感器通过 Oracle Enterprise Manager 搜索特定实例,或者使用 Oracle SOA Suite API,您可能希望对组合传感器名称使用特定的命名约定。[8]

并不需要 40 页的编码约定文档 — 一页 wiki 页面通常就可以满足要求。

将常用 Oracle SOA Suite API 包装在更简单的自定义 API 中

SOA Suite API 的设计是非常通用的,有非常充分的理由。其目的是允许通过多个工具、多个平台、多种方式使用这些 API。但通用性是有代价的:出现可能与特定环境无关的选项、命名可能过于抽象等。

将通用的随取随用的 Oracle SOA Suite API(尤其是 TaskQueryService 和 TaskService)包装在自己的 API 中然后可以向客户端提供,很快就可见到效果。如果可能,请为这些 API 指定自描述性名称并使它们用于单一目的。这将简化开发人员的工作,降低出错的潜在风险。另一个积极的作用是,当随取随用的 Oracle SOA Suite API 升级到更新版本的 Oracle SOA Suite 时,包装器 API 将对客户端屏蔽这些 API 中的潜在更改。

构建敏捷性 — 使用 DVM 和业务规则

在您的环境中,同一组合有过多不同版本可能会难以管理。同一服务有两三个版本不会有任何问题,这可以支持向后兼容性和敏捷性(不强制服务使用者全部立即迁移到新版本)。但十个或二十个版本就太多了,会导致失控。遗憾的是,用同一版本号重新部署意味着该组合的运行中实例将被标记为陈旧。如果您还有运行中的实例,就要考虑部署为新版本。

部署新的组合版本并不总是因为添加或更改了功能。小的设计更改或更新也有可能导致新的版本部署。

最佳实践是使用域值映射 (DVM) 和业务规则来封装快速变化的逻辑(业务规则)或值和查询 (DVM)。这些组件可以在运行时更新而不必重新部署组合 [17],因此不必停止所有运行中实例。如果可以预见到未来可能需要进行更改,请在开始时使用 DVM 和业务规则。不要将这样的逻辑硬编码到 BPEL 和 BPM 活动或中介器中。

考虑一个服务示例,该服务获取一个文件并将其内容提供给另一个服务。最初我们可能需要从 PDF 文件开始,读取扩展名为 *.PDF 的文件并将其内容映射到 application/pdf mimetype。这个值对可以硬编码在中介器中,但当需要支持其他扩展名/mimetype 组合时,将需要更改 XSLT 并重新部署组合。相反,如果使用 DVM,则可以使用 SOA Composer Web 控制台在运行时添加任何新的扩展名/mimetype 组合,而不必修改和重新部署组合。

另一个示例是基于客户状态评估折扣级别。这些级别将来很可能会发生变化,变化速度可能比组合中实现的整个业务逻辑还快。最佳对策是使用业务规则。这将允许更新各种折扣率而不必重新部署组合。考虑使用新的 11g 决策表来捕获这些规则,这些决策表更直观,非常强大,足以应付各种使用情况。

在这种情形下,业务规则的另一个有用特性是能够指定规则的有效起始日期。有些业务规则(及对现有业务规则的更改)只应在特定日期(如规则或法规生效的日期)之后生效。

故障处理

在服务和流程建模过程中,如果将处理所有异常行为的逻辑与“正常”流程逻辑混放在一起,则会产生一种常见的缺陷。

以发票处理流程为例。在发票金额超过批准金额的情况下,我们可以添加人工任务并将其指派给财务部门。这类情况可称作业务故障。这些“异常”涉及到业务,且随每个业务服务而不同。在 SOA 组合中对这些活动进行建模是完全合理的。

另一方面,还有另一类故障:技术或系统故障(有效负载错误、端点不可用等)。处理这些故障的逻辑也可以纳入到同一 SOA 组合内。但这样的逻辑与功能或业务需求无关,可能对一些(或所有)组合都一样。向每个组合添加相同的对技术错误的故障处理逻辑,会导致在这些 SOA 组合中存在重复的逻辑并且样板化代码和功能逻辑相混杂。样板化代码充斥 SOA 组合,可让它们的设计看起来像高度复杂的印刷电路板。

如果通用故障处理逻辑嵌入在所有组合中,则创建的 SOA 组合越多,越难更改此逻辑。同时,样板化代码和业务逻辑的混合导致难以维护监督。最佳实践是在 SOA 组件之外通过单独的故障策略文件实现对技术和系统故障的处理。Oracle SOA Suite 为此提供了随取随用的故障策略框架。

您可以为每个组合添加故障策略配置,也可以在 MDS 中集中添加。如果您关注的是低起步、高成长,建议您创建一个通用故障处理机制并将其存储在 MDS 中以便重用。这样可以更轻松地更改组合的故障处理(它只在一个地方定义),更轻松地为新组合添加故障处理功能(只需引用 MDS 构件)。

开始构建组合服务之前,请考虑可能会出现何种故障以及该故障的后果。如果可能,您是否需要修补以纠正重复的条目?或者,您可否使用 XA(全局事务)以便自动回滚事务?使用 XA 时,很重要的一点就是测试和检查每个组件是否都参与该事务。否则,适配器可能在全局事务被提交或回滚之前进行提交(可能通过重试),从而导致重复的条目。使用 AQ 或 JMS 作为全局事务的起点时,最佳实践是配置一个最大重试次数或错误队列以避免无限循环。

最后,您应从一开始就考虑哪些故障处理和预防功能应驻留在服务总线 (OSB) 层与流程层(BPEL 和 BPM)。[4]

单元测试

Oracle SOA Suite 支持您连同组合一起部署单元测试。您需要 Java 开发人员为其所有代码提供单元测试,正是出于同样的原因,您应充分利用上述特性。此外,这些测试在确保基础架构补丁或升级不会带来任何退步方面至关重要。建议您使单元测试成为构建过程的一个不可或缺的组成部分,具体办法是,使用 Oracle SOA Suite 附带的特定 Ant 任务来运行单元测试。有关背景信息,请参见 [15][16]

架构考虑事项

软件架构与设计之间并非总是界线分明。在本节中,我们将找出一些超越组合设计的最佳实践,并讨论构造、分类和治理服务的最佳实践。

服务分类

在业务价值和粒度方面,一个返回两个日期之间的工作日天数的简单组合不同于一个实现银行抵押贷款业务流程的组合。

并非所有服务都是平等的。人们通常使用前缀来标明服务类型:业务服务、流程服务、基本服务、组合服务等等。

如果希望拓展 SOA 工作,您将需要一个结构来将服务划分为各种类别。这是必要的,因为不同类型的服务适用不同的原则。下面是这些指导原则的示例:出于性能的原因,两个自动化服务的简单服务组合应在 OSB 中完成;基本服务不应包含流程逻辑;而业务服务应在 BPEL 或 BPM 中实现。

最佳实践是在进行 SOA 工作之初有一个简单、具体的服务分类。勾画出服务类型的整体视图,将各种服务类型与实现它们的各种中间件组件相对应,并确定不同服务类型的治理原则。

您不必设计出完善的 SOA 治理方案,但几个命名约定和分类会十分有用。

服务粒度

服务应具有什么样的粒度?这是在 SOA 领域最常被问到的问题之一。对此没有唯一、确定的答案,但有几个指导原则可以帮助您找到适合您情况的答案。

从一开始进行 SOA 工作就考虑粒度非常重要。尽管重构是软件开发人员工作的一部分,但我们不希望只是因为我们没有想清楚组合应是多大或多小,就得在每个阶段从结构上重构所有组合。确定粒度时,最重要的方面是可能的可重用性:如果一段软件代码被(或将被)多个使用者使用,那么这段代码应是一个单独的服务。否则,我们可以将这段软件代码合并到一个大的组合中加以隐藏。

更具体地说,对于 SOA 组合这意味着:

  • 如果一个组件(如业务规则、BPEL 组件等)是可重用的,则专门创建一个 SOA 组合来容纳它。
  • 否则,就将这个非可重用组件嵌入一个现有 SOA 组合或将其与另一个 SOA 组合合并以创建可(重新)使用的部件。

这种方法还可以帮助隐藏外界不需要知道的小段软件代码 — 这也称为“封装”或“实现隐藏”。只有在组件被外界实际调用时,您才应将它们作为服务公开;而其他组件不应公开。[11]

尽管可重用性对于定义 SOA 组合的粒度至关重要,但它不是唯一的因素。您还应在组织和管理方面进行一些考虑。例如:

  • 更改速度:快速更改的组件应与更稳定的组件分离。
  • 可用性:为需要 24/7 随时可用的对象创建一个单独的 SOA 组合,以便让它与不太重要或不经常使用的其他组件分离,这么做是明智的。
  • 所有权:理想情况下,一个服务或流程应只有一个(业务)所有者。如果确定有多个所有者,则该组合可能过大。

通过事件实现分离

同步交互往往更易于理解,大多数较简单的集成项目通常都采用同步交互模式。但异步对于可伸缩性非常重要。此外,业务往往按事件来考虑:考虑收到一个新发票、在航班上检查行李包或雇佣新员工。让您的 SOA 模拟这种模式是明智之举。

考虑以下因素:

  • 人工交互不可能同步 — 这种交互必定是异步的。
  • 在同步世界,容错能力是由系统中最弱的一个组件决定的:该组件发生故障即意味着需要重新处理链中的所有步骤。
  • 在异步的世界,可伸缩性是由链中最慢的服务决定的:如果一个可以在一小时内处理数百万条突发消息的服务调用一个低吞吐量的服务,会出现什么情况?
  • 对于任何一个给定的消息,需要收到该消息的相关方的名单可能很长,并且是无限的(可能随时间而增长)。我们是否将为每个需要收到这些消息的新服务扩展中介器(扇出)?

通过业务事件或消息传递来构建异步模式将提供应对以上问题所需的分离级别。更具体地说:

  • 分离。发布服务不需要知道使用服务及其操作。发布服务可以只发布事件并返回执行下一步处理,无需担心谁可能需要该事件。这减少了服务之间相互依赖关系的数量。
  • 易于部署和管理。如果接收端关闭,消息不会丢失。在持久订阅(AQ 和 JMS 支持;EDN 不支持)的情况下,消息中间件将存储这些事件,直到接收方重新启动。管理团队可以使一些服务脱机,而不必停止整个 SOA 基础架构。
  • 限制。当产生的消息超出接收方的处理能力时,消息队列可以对消息进行缓存。当然,这只对突发 的临时情况有用。如果这种情况持续下去,则没有灵丹妙药:您将需要扩展使用方。而且,记住队列并不是一个无底洞:它也会满溢(如当存储用完时)。

有关详细信息,请参见 [13][14]

版本控制

版本控制在 SOA 中可能有不同含义:构件版本控制(使用版本控制系统存储和管理软件构件)或运行时版本控制(给行为不同的服务标上不同标签)。尽管这两种并非毫无联系,但每种通常按自己的速度发展。本节重点介绍运行时版本控制。

考虑只能存储版本 1.0 的 PDF 文档的 DocumentService,添加对版本 1.1 的 DOCX 的支持,最终支持版本 2.0 的所有扩展。有趣的是,在生产中的任何一个给定时间点可能出现同一服务的多个版本共存的情况。这允许使用者按自己的速度进行升级:只要他们需要访问新的功能(对新文档类型的支持)且准备好在自己那端处理它们。

在版本方面,Oracle SOA Suite 是灵活的,允许您推出自己的喜爱的版本控制约定,无论是“3”还是“3.0.0”。这种灵活性还意味着您应准备一些约定以确保一致性。除了一致性问题之外,在该领域缺乏明确性可能导致更严重的问题:例如,引入不保留向后兼容性但其版本号并未明确反映此事实的新服务。

最佳实践是在合约 (WSDL) 和消息定义 (XSD) 中包括版本控制信息(即版本号)。将版本号包括在命名空间中是实现此目标的一个好办法。W3C 在 XSLT、XSD 等命名空间中也使用此方法。

一些版本控制提示和技巧:

  • 在引入合约和接口未更改的错误修复时决定您是否需要更改版本号。
  • 如果合约和接口是向后兼容的,可考虑覆盖短期存在和完全自动化的服务的默认服务版本。注意,建议您在服务未被使用的安静时段升级服务。
  • 指定将对服务支持的最大并发版本数,通常是 2 或 3。关键是在可管理性(管理员不希望在任何给定时刻部署太多进程)和灵活性(服务使用者希望有一些时间提前量以便能够适应给定服务的新版本)之间找到恰当的平衡。
  • 对部署新版本后服务保持有效的固定时段达成一致,例如,向使用者保证给定版本将在新版本发布后三个月内保持有效。
  • 为服务定义一个简单的服务生命周期,并跟踪服务状态(例如在 wiki 上)。例如:已标识 开发中 已测试 生产中 已弃用 不可用。向您的运营和开发团队以及(可能的)使用者发布此类信息。
  • 定义版本控制方案。例如,x.y.z,其中 x 代表主要版本,y 代表次要版本,z 代表错误修复。

注册表和信息库

SOA 环境由多个共同提供业务价值的服务组成。通常个人不可能完全了解整个服务环境和依赖关系。这正是注册表和信息库发挥作用的地方。注册表本质上是所有服务及其关键特征的列表,而信息库存储重要实体服务构件,如 WSDL、XSD、SLA 等。利益相关方可以使用注册表和信息库来深入了解可用服务以及如何使用它们。

对于您在启动 SOA 计划时应记录的服务信息,下面给出一些指示:

  • 按服务类型组织信息:例如,要区别业务服务、组织服务和应用程序服务。
  • 记录服务之间的依赖关系:有哪些其他服务调用特定服务?该服务依赖哪些其他服务?
  • 对于每个服务,列出服务名、所有者、版本、状态(已标识、开发中、生产中、已弃用等)和描述。
  • 对于自动化服务,为每个环境添加相关的 WSDL、XSD 和端点位置。

当您开始 SOA 工作时,您并不总是能够访问完整的治理信息库,如 Oracle Enterprise Repository (OER)。在这种情况下,wiki 可能是记录 SOA 环境的一个合适的选择。但随着您的 SOA 工作的增加,在简单的 wiki 页面中跟踪依赖关系之类的事物的难度将呈指数级增长。到那时您将可能需要升级到完善的信息库工具(如 OER),并将 wiki 上记录的信息提供给它。最重要的是,在将任何服务转入生产环境时,要通过强制进行更新来确保此信息始终保持最新。

总结

本文介绍了读者在开始部署 Oracle SOA Suite 之前应考虑的一系列主题。所有这些问题,如果及早进行考虑,是相当易于解决的,但如果在 SOA 项目的稍后阶段才考虑,它们可能会麻烦得惊人。与通常的情况一样,认识、一致性和记录是成功实现面向服务的架构的最佳秘方。

参考资料

截至本文写作之时,Oracle SOA Suite 的最新版本是 11.1.5.0 (11gR1 PS4)。以下所有 Oracle 文档链接均指向该版本的文档库。我们还提供了从顶级库开始的导航路径。我们鼓励您访问 OTN 上的 Oracle SOA Suite 产品页面:http://www.oracle.com/technetwork/cn/middleware/soasuite 并导航到“文档”选项卡以找到最新、最高版本的文档库。

  1. Oracle SOA Suite 11.1.1.5 (PS4) 文档库
  2. 适用于 SOA 的企业部署指南 (EDG)
    (doc library > Oracle SOA Suite, Business Process Management and Web Services > Oracle SOA Suite > Enterprise Deployment Guide)
  3. Oracle 融合中间件高可用性指南
    (doc library > Cross Suite Documentation > Cross Suite Documentation)
  4. Oracle SOA Suite 11g 中的故障处理
    Ronald van Luttikhuizen 和 Guido Schmutz 在 ODTUG Kaleidoscope 2011 上的演示文稿
  5. 针对 Oracle SOA Suite 和 Oracle Business Process Management Suite 11g 的 Oracle 融合中间件管理员指南:第 5 章“部署 SOA 组合应用程序”
    (doc library > Oracle SOA Suite, Business Process Management and Web Services > Oracle SOA Suite > Administrator's Guide)
  6. Oracle 融合中间件 Oracle WebLogic Scripting Tool
    (doc library > Use the Oracle WebLogic Scripting Tool (WLST))
  7. 规范最佳实践
    Chris Judson 发表的博文
  8. 通过端到端跟踪与组合传感器提高可见性
    Demed L'Her 发表的博文
  9. Oracle 融合中间件 Oracle SOA Suite 和 Oracle Business Process Management Suite 11g 安装指南 — 附录 A:Oracle SOA Suite 和 Oracle Business Process Management Suite 安装屏幕
    (doc library > Oracle SOA Suite, Business Process Management and Web Services > Oracle SOA Suite > Installation Guide)
  10. 最佳实践 2 — Web 服务
    Ronald van Luttikhuizen 发表的博文
  11. 通过 SCA 消除“过度提供服务”
    Ronald van Luttikhuizen 发表的博文
  12. AIA 11g:启动服务器时分离服务和避免无效组合的最佳实践
    Gerhard Drasch 发表的博文
  13. Oracle SOA Suite 11g 中的事件处理概述
    Ronald van Luttikhuizen 在 ODTUG Kaleidoscope 2011 上的演示文稿
  14. 事件与 SOA
    Ronald van Luttikhuizen 发表的博文
  15. 测试基于 Oracle SOA Suite 11g 的系统的最佳实践
    Guido Schmutz 的演示文稿
  16. 使用 Rules Designer 测试 Oracle 业务规则
    Bob Webster 发表的博文
  17. 使用 SOA Composer 在运行时编辑 Oracle 域值映射和业务规则
    Eric Elzinga 发表的博文

Edwin Biemond — Amis Services B.V. 的架构师 LinkedIn Oracle ACE
Ronald van Luttikhuizen — Vennster 的执行合伙人和架构师 LinkedIn Oracle ACE 总监
Demed L'Her — Oracle 产品管理高级总监 LinkedIn