示例:SOA 模型示例

问题描述 回到页首

在此示例中,我们来看看一个选择将其销售点(PoS)终端的应用程序所使用的特定功能作为服务重新实施的零售商所面临的问题。现在,贸易应用程序是作为单个应用程序开发的,该应用程序有非常紧密耦合的组件,但有些组件驻留在商店内服务器(ISS)上,有些请求甚至被 ISS 转发到位于企业中心的服务器。问题是,由于组件的紧密耦合以及在组件的开发和不同组件之间的连接中使用了专有协议和技术,所以一般的商店基础结构和特定的贸易应用程序很难维护。

在以前的商店系统中,PoS 终端使用专有和低容量的机器,对于商店内和商店外的带宽有限制,现在这些限制大多已不存在了。 知道了这一点,以及现有的在企业后端系统中向面向服务的体系结构的转变,我们已决定 ISS 提供的一些功能和中央服务器应作为服务对贸易应用程序显现。

项目范围和目标 回到页首

最初要考虑选择的功能都有一个共同的模式:它们当前要求贸易应用程序中的逻辑在多个数据存储器中查询信息。这样,提出的服务不仅提供了一个公共的接口,还使贸易应用程序与数据位置的明确了解脱离,且不必处理多个协议。 这些服务将通过 RMI 从贸易应用程序访问 ISS 服务,并使用 SOAP over JMS 从 ISS 到集中服务。

服务标识 回到页首

以下内容概述了体系结构团队所执行的步骤,该团队包括拥有 IT 组织的零售商成员和作为开发面向服务解决方案的专家引入的外部顾问。请注意以下步骤并不表示推荐使用的 RUP 活动,只是列出了实际项目的活动。

重要的是,注意此项目将改进当前现有功能的技术实施,所以没有花太多的时间在业务建模或分析上,因为我们可以复用为原始贸易应用程序创建的模型。当前的模型集(在下图的左边)遵循以下所示的结构,其中显示了 RUP 用例模型、贸易应用程序公共组件的分析模型、详细的设计模型和一组用于 Java 开发团队的实施模型。

文本内容中所述的图。

服务模型被作为分析模型的改进引入(在上图的右边)到一组具有其自己的实施模型的服务中。现在可修改贸易应用程序设计以显示这些公共服务的用法,另外还显示了贸易应用程序和服务 Java 模型之间的关系。

服务模型创建

如下图所示,存储支持服务模型是根据软件服务的 UML 概要文件和模板模型(包含在 Rational Software Architect 中)创建的。如以上所示,该模型被标识为分析模型的改进。正如您所见,在显示模板推荐的视图之间依赖关系的概述图中体现了该结构。

文本内容中所述的图。

用视图包旁边的图链接可以快速浏览模型,这些链接将在以下部分完成。

有关更多信息,请参阅工具向导在 RSA 中创建服务模型

标识服务分区(位置)

从以上对问题的描述可知,对系统分区有多种方法,例如我们可以引入代表库存管理、服务/保证管理、销售点操作(查找价格、客户等)的分区。但是,这些不是体系结构的主要问题,所以添加到模型的分区代表在商店中或在企业级别提供的服务的逻辑位置。

文本内容中所述的图。

当我们说这些是逻辑分区时,我们就确定了商店服务分区包含一组在商店级别实例化的服务,我们并未描述这些服务的物理部署(单服务器、集群等)。为体系结构提供这些逻辑分区来代表解决方案的重要方面。

另请注意,在上图中,体系结构引入了另一个元素,即贸易应用程序本身,以描述应用程序和服务之间的通信。贸易应用程序是 UML 2.0 组件,其构造型为服务使用者

有关更多信息,请参阅解决方案分区概念。

分析现有功能

下一步是分析贸易应用程序的当前实施,查看以上问题说明中标识的数据库访问的详细信息。因此生成了下表(注意它仅包含客户和库存查找的详细信息)。
 
名称 技术 输入 输出 注释
sp_get_custlist_by_phone SQL 服务器存储过程 phonenum(10 个字符) 列表:
custid (id)
custname(40 个字符)
此存储过程通过电话号码返回了客户详细资料列表,该列表可呈现给客户以供选择。sp_get_cust_details 调用用于返回一个客户记录。
sp_get_cust_details SQL 服务器存储过程 custid (id) 客户记录 返回了客户的详细资料:姓名、地址、联系信息等。
CUST_QUERY IBM MQSeries phonenum(10 个字符)
返回队列名称(120 个字符)
相关标识(120 个字符)
不适用 应用程序将要查询的客户的详细资料放入此队列,消息被交付到中心,在那里服务器将应答消息公布到标识的返回队列。
<return-queue-name> IBM MQSeries 不适用 相关标识(120 个字符)
客户记录列表
返回客户记录时,返回消息还包含相关标识,以确保可将应答与给定的请求关联。这允许商店内的服务器有一个所有终端的返回队列,终端用其相关标识来查询响应消息的队列。
sp_get_invstate_for_sku SQL 服务器存储过程 sku(13 个字符) 库存记录
INVENTORY_QUERY IBM MQSeries sku(13 个字符)
返回队列名称(120 个字符)
相关标识(120 个字符)
不适用
<return-queue-name> IBM MQSeries 不适用 库存记录

正如您所见,这些条目代表现有的实施,该实施将被替换为新的实施,但将保持原来的用途和功能。

初始服务规范开发

活动服务标识引入了一些支持解决方案所需的标识服务的技术和对服务的操作。在此示例中,我们看到了一种以旧换新的形式,将现有功能转换为服务模型和特定的服务实施技术。要执行此操作,首先要开发服务规范集合,该集合将提供实施以上所述功能的服务合同。 下图显示了在此阶段创建的三个当前为空的服务规范,每一个用于介绍中讨论的一种服务。

文本内容中所述的图。

接着,我们分析服务可能的使用模式,例如,我们实际上可以有两种服务,一种用于商店内,一种用于企业,其中,数据库访问和企业访问的逻辑都包括在商店内服务中。我们也可选择在商店中有一个外观服务,该服务包括该逻辑并调用两个相同的服务,一个包括本地数据库访问,另一个包括企业访问。第二种选择在更改对两个商店的逻辑访问方面增加了灵活性,但对于比较简单的功能而言则增加了开销和通信成本。所以,对于客户查找和库存查找,选择了第一个选项。虽然服务分发的详细信息和服务提供者尚未确定,但是如果仅侧重于服务规范,则服务标识将有效得多。

要标识这些服务的角色和职责,我们使用服务协作和一个特定的 UML 2.0 组合结构图,该图代表客户查找的服务的配置。该结构图如下所示,我们可以看到代表协作中每个元素的 UML 2.0 部分。注意,贸易应用程序和商店内服务之间以及商店内服务和企业服务之间的接口的构造型为服务通道,并标识要使用的绑定(如以上所标识的 RMI 或 JMS)。商店内服务和本地数据库组件(较迟)之间接口的绑定未定义。

文本内容中所述的图。

这里要注意的一个关键元素是 LocalCustomerLookupProvider 是一个生成的服务,它是围绕数据库查询的一层很薄的包装程序服务,有一个代表 SQL 选择的操作。该方法是由商店内客户查找服务通过直接访问数据库选择的,以允许本地服务包括其他业务规则,或甚至在以后成为更完整的服务。

但是,此图仅显示了协作的结构,以下交互图(UML 2.0 时序图)代表了服务之间的实际通信。请注意我们已将操作 getCustomerByPhone 添加到服务规范。另请注意,UML 2.0 允许指定时序图的可选“片段”,在此情况下,表示如果本地查找失败,我们将只与企业服务通信。

文本内容中所述的图。

将静态结构与通信图结合使我们能够记录服务组合和协作,并在此情况下意识到对服务规范只需执行单个操作。

有关更多信息,请参阅活动服务标识

服务设计 回到页首

获得来自“服务标识”活动的模型后,我们将对一组候选服务的确定转换为要构建的服务的详细设计。第一步是制订实现以上规范的服务规范;正如您所能想到的,在服务如何实现以上模型的服务规范方面要作出许多决定。在此示例中,我们有相当简单的结构,但该结构可能对于许多项目都是相同的。在此情况下,我们有一个服务提供者,提出实现一个规范的一个服务。当然,每个供应商都可以有多个服务。我们还注意到此模型中各服务之间的一些使用关系,这些依赖关系对于理解服务如何随时间演进是很重要的。

文本内容中所述的图。

此结构允许我们现在更多地转移到分发空间,而当服务提供者表示部署服务模型的单元时,模型仍然是服务的逻辑视图。定义组合服务也需要服务提供者,因为服务本身(UML 2.0 端口)不能拥有描述该组合所需的结构。

消息设计

在服务标识活动中,我们前面未谈到关于服务规范中描述的各操作之间交换的实际消息。这可能是很普通的方法,根据推迟消息的详细设计的操作来捕获服务的职责,在某些情况下,此方法被倒转,消息结构已提前知道,然后被聚集为一组操作。

在此情况下,我们能利用作为组件分析模型的一部分开发的领域模型(以前开发的资产),所以我们的消息模型并非无任何内容,而是标识了要复用的领域模型的子集。以下的示例说明了这个关系,领域类完全不知道技术和平台,另一方面,我们的消息被认为是数据传输对象和在服务之间传递的结构。所以我们不改变领域模型,而是在类结构“之外”创建消息,包含内部的元素。

文本内容中所述的图。

有关更多信息,请参阅概念消息设计

服务实现 回到页首

在此情况下,我们将侧重于实现商店内的客户查找服务;此服务通常在从服务模型到设计模型的转变中。该转变本身在指南中有记录,它导致以下模型结构。

文本内容中所述的图。

虽然这仍是设计模型,我们可以使用工具将此模型进一步变换为以下所示的 EJB 实施。基本上,此实施是从以上的 CustomerByPhone 类转变而来,详细描述客户的消息被转变为用于查询数据库的实体 bean。

文本内容中所述的图。

有关更多信息,请参阅指南从服务到服务组件