随笔 - 181, 文章 - 2, 评论 - 85, 引用 - 0
数据加载中……

*****普及环境中面向服务的体系结构(SOA)

本文描述了一种面向服务的方法,用于为普及设备提供公用接口。本文用财政案例演示了如何通过关键 Web 服务应用程序类型,包括事务、通讯、基于位置的服务以及更多,将 Web 服务扩展到普及环境中。

引言

普及运算是信息技术的下一阶段。业界分析家预言移动设备将是下一个范例转换,并且包括 IBM 在内的供应商都在为构建普及运算应用程序大力投资,以开发最好的工具。象移动电话、PDA、寻呼机这样的普及设备在数量上已经远远超过台式机和膝上型电脑,而且趋势正在扩大。除此还正在用严格的运算能力和通讯链接构建各种各样的装置,例如空气调节系统、吸油烟机、汽车监控系统,为了在除 PC 和工作站以外的设备上构建应用程序,首先要了解在新的运算环境中的巨大投资。

在本文中,我们提出了一种面向服务的方法,用于提供独立于设备的公用接口。该方法为普及运算环境作出了很大的贡献。我们的目的是指出用于各种应用程序类型的独特服务。我们将用一个财政案例来演示面向服务的体系结构 (SOA) 在普及环境中的扩展。本文首先简要介绍了 Web 服务和普及运算环境。接着是概述部分,描述了如何通过关键 Web 服务应用程序类型,包括事务、通讯、基于位置的服务、同步、设备管理、数据管理和媒体应用程序,将 Web 服务扩展到普及环境中。







SOA 概述

从概念上讲,SOA 是一种实现动态电子商务的体系结构。它是一种软件系统设计方法,通过已经发布的和可发现的接口为终端用户应用程序或其它服务提供服务。服务为封装离散的业务功能提供了一个更好的方法,因此,服务也是开发支持业务流程应用程序的一个好方法。


图 1. 通常的 SOA 环境
通常的 SOA 环境

Web 服务组件

在任何面向服务的环境中都需要进行一些基本操作:

  • 需要创建 Web 服务,并定义其接口和调用方法。
  • 需要将 Web 服务发布到一个或更多的内联网(Intranet)或互联网(Internet)储存库中,供潜在的用户查找。
  • 需要查找 Web 服务供潜在的用户调用。
  • 无论基于什么好处都要调用 Web 服务。
  • 当 Web 服务不再可用或不再需要时,需取消其发布。

图 2. SOA 模型
SOA 模型

服务是一个逻辑实体,其合约是由一个或多个已经发布的接口定义的。

服务提供者是一个网络节点,它为处理一系列特定任务的软件资源提供服务接口。服务提供者节点能代表商业实体的服务,或者它甚至能代表可重用子系统(实现服务规范的软件实体)的服务接口。

服务请求者是一个网络节点,它发现并调用其它的软件服务来提供商业解决方案。服务请求者节点常常代表执行远程过程调用分布式对象或者服务提供者的商业应用程序组件。提供者节点可能就在本地的企业内部网内,或者在远端的因特网上。从概念上来说,SOA 本质上是将网络、传输协议和安全细节留给特定的实现来处理。通常称为 客户端,但是,服务请求者也可以是终端用户应用程序或别的服务。

服务定位器是一类充当注册表的特定服务提供者,允许查找服务提供者接口和服务位置。

服务中介者是一个网络节点,作为储存库、电话黄页或票据交换所,产生由服务提供者发布的软件接口。商业实体或者独立的运营商能代表服务中介者。

这 3 种 SOA 参与者、服务提供者、服务中介者以及服务请求者通过 3 个基本操作: 发布查找绑定相互作用。服务提供者向服务中介者 发布服务。服务请求者通过服务中介者查找所需的服务,并绑定到这些服务上。

SOA 实现技术

SOA 实现技术包括:

  • XML:可扩充标记语言 (Extensible Markup Language) 1.0 标准是一个基于文本的 World Wide Web 组织 (W3C) 规范的标记语言。与 HTML 使用标签来描述外观和数据不同,XML 严格地定义可移植的结构化数据。它可以作为定义数据描述语言的语言,例如标记语法或词汇、交换格式和通讯协议。
  • SOAP:简单对象访问协议 (Simple Object Access Protocol) 是一个基于 XML 的,用于在分布式环境下交换信息的轻量级协议。SOAP 在请求者和提供者对象之间定义了一个通讯协议,这样,在面向对象编程流行的环境中,该请求对象可以在提供的对象上执行远程方法调用。SOAP 规范是由 Microsoft、IBM、Lotus、UserLand 和 DevelopMentor 联合制订的。该规范随后发展并建立了 W3C XML 协议工作组,有超过三十家公司参与其中。在大多数厂商的 SOA 实现中,SOAP 为分布式对象通讯构建了基础。尽管 SOA 没有定义通讯协议,但由于在 SOA 实现中的普遍使用,最近 SOAP 被称为面向服务的架构协议 (Services-Oriented Architecture Protocol)。SOAP 的优点在于它完全和厂商无关,相对于平台、操作系统、目标模型和编程语言可以独立实现。另外,传输和语言绑定以及数据编码的参数选择都是由实现决定的。
  • WSDL:Web 服务描述语言 (Web Services Description Language) 是一个提供描述服务 IDL 标准方法的 XML 词汇。WSDL 是融合 NASSL (IBM) 和 SDL (Microsoft) 之间的活动产物。它为服务提供者提供了一个简单的方法,描述远程方法调用 (RMI) 的请求消息和响应消息的格式。WSDL 不依赖于底层的协议和编码要求来涉及服务 IDL 这个主题。通常,WSDL 提供一种抽象的语言,利用各自的参数和数据类型来定义被发布的操作。该语言还涉及了服务的位置和绑定细节的定义。
  • UDDI:统一描述、发现和集成 (Universal Description, Discovery, and Integration) 规范提供了一组公用的 SOAP API,使得服务中介得以实现。UDDI 规范是由 IBM、Microsoft 和 Ariba 制定的,促进了基于 Web 的服务的创建、描述、发现和集成。在 UDDI.org 之后的动机是为 B2B 互操作性定义一个标准。

Web 服务应用程序设计


图 3. Web 服务标准
Web 服务标准

Web 服务通讯可以使用 XML,但它可能要传输二进制数据,它通常使用 SOAP 消息头,但是不需要为消息体进行 SOAP 编码。它可能用 HTTP 进行传输,但是也还可以用 SMTP 或其它的方法。为描述和发现 Web 服务,有两种定义完好的标准:WSDL 和 UDDI。

背景及相关工作

用面向服务的方法进行运算已经引起了研究人员和业界的广泛关注。主要目的包括用于构建软件组件的面向服务的编程 (SOP) 和用于分布式应用程序的面向服务的体系结构 (SOA)。

SOP 引入并实施面向服务的编程,但它是面向启用进程内和进程间通讯的软件组件的开发的。用 SOP 开发的软件程序可以作为多线程程序,在多线程程序中,各个线程可以通过明确定义的接口交换消息。程序的组件设计集中在为组件所提供的服务定义接口。SOP 提供的特性包括合同、组件、连接、容器和上下文。SOP 软件应该具有联合性、易部署性、移动性、安全性和可用性。

SOA 建立在 SOP 上来构建系统和应用程序以获取软件组件所提供的服务的最大限度的复用,同时要确保他们交互中的松散耦合。基本元素是服务,SOA 指定一组实体(服务提供者、服务消费者、服务注册表、服务条款、服务代理和服务契约),这些实体详细说明了如何提供和消费服务。遵循 SOA 观点的系统必须要有服务,这些服务是可互操作的、独立的、模块化的、位置明确的、松耦合的并且可以通过网络查找其地址。

Web 服务技术是以 SOA 概念为基础的。该项技术直接面向企业应用程序集成,为半自动交互式和组织内部的业务流程提供了公用数据交换平台。构成 Web 服务的技术包括 XML、UDDI、HTTP、SOAP 和 WSDL。XML 用于定义 Web 服务间消息的结构。UDDI 是可供查询的 Web 服务资源库。HTTP 是底层的通讯媒介。SOAP 是交换消息的容器。WSDL 用于描述 Web 服务。相关研究已经进展到涉及交互和协调性问题,虽然没有提及或整合针对 Web 服务合成的研究,反之亦然。

Jini 是另一个主要的 SOA 目标,它已经以服务为基础直接面向构建本地运算环境。假设设备能提供服务,并且 Jini 指定特定的特性,例如发现、结合、查找、联合、租赁以及其它的能实现网络部署的特性。Jini 紧密绑定到 Java TM 编程语言。例如,通过 Java RMI 进行通讯,以 Java 对象接口作为服务接口规范。







在普及环境中使用 SOA

下面的部分概述了普及环境中的 SOA 和 Web 服务。

普及环境简介

普及运算方案可以看作是针对特定问题的特定解决方案,其中问题通常表现为案例。从这方面来看,他们趋向于传统的嵌入式系统设计,只是规模更大一些,而且添加了网络。对于嵌入式系统设计,各种方案倾向于创建自定制解决方案,这些解决方案是专有的而且缺乏可扩展性。看上去缺少的东西正好适合于编程普及运算环境。相反,各种普及运算案例似乎设想了一种软件的无缝系统,该系统根据用户的期望和目的运行。我们认为这种观点既与可能越来越多的采用这种方案这个现实矛盾,又与各普及运算设备供应商无疑会扩大生产的多样性相矛盾。因此,我们提出了一种标准的基于服务的编程环境供普及运算所采用。

普及运算是由 NIST(简写)为强大新兴趋势的朝向所定义的:

  • 无数的、方便使用的、通常无形的运算设备
  • 频繁移动的或内嵌在环境中的
  • 与日益无处不在的网络结构连接

目的是为了使任何需要运算的地方更容易。各种研究人员已经证实了为实现这个设想,需要网络和中间件基础设施。这种普及基础设施的特征包括规模、移动性和普遍存在性。这个规模将使任何现有的设施显得太矮小。基于这一点,我们可以推断出基础架构必须要涉及到各种附加问题。由于故障和/或连接中断是一个至关重要的问题,而且随着组件数量的增加,组件发生故障的可能性也随之扩大。即使系统不出故障,它也必须有容错功能。在本质上,基础架构应该是对等的,而不是客户端/服务器端或多层的形式,但目前在中间件和构建数据网络中通常使用的是这些形式。就因特网而言,这么大的系统能否有单独的授权域很是值得怀疑。假设有大量能移动的授权域,还需要一些访问者身份,既用于连接到外部网络的移动设备,又用于他们的所有者下面的移动应用程序。因此,访问者身份必须既要保护外部网络的完整性又要保护移动数据的安全性。普遍存在性和可移动性意味着设备期望能一直连接到基础设施。最后,这样的系统能不异构很是值得怀疑。

另一方面,普及运算方案常常采用提供单一集成解决方案的方法,通常是针对特定案例或案例集的。因此,普及运算需要一个能用于编程的公用抽象,在这个抽象中各种问题都可以解决。这种抽象必须足够强大能捕获现有的方案,而且要足够灵活能在普及运算内实现各种突出问题解决方案的开发。我们认为基于服务的方法可以提供这样的抽象。该方法能为普及运算环境作出重大的贡献。

首先,它提供了一种查看普及运算系统的方法。目前,大量关于普及运算的研究结果都是围绕案例展开的。因此,普及运算到底是什么还不是很清楚。基于服务的方法将普及运算定义为一种无处不在的可用的服务环境。

其次,它提供了一个架构,在这个架构中可以查看现有的普及运算方案。因此,我们可以确定那些方案所缺少的特征。我们还可以以各种方案实现我们的服务视图的方法为基础对这些方案进行比较。

第三,我们的方法允许在无处不在的可用的服务环境中进行普及运算的增量开发。

普及运算安全性

普及运算环境依靠各种客户端和服务器间通过不同网络所传输的信息的交换。在这种设置中,由于信息要从源传输到目的地,通常要冒数据被拦截的危险。Web 服务事务也要冒同样的安全性危险。在使用 SOAP 进行传输的 Web 服务事务中,服务调用方和服务提供方之间所传送的数据是简单的 XML,因此任何人拦截了该消息都能读取所交换的数据。在 Web 服务案例中,基于以下原因,安全性方面变得更复杂:

  • 可以用不同的应用程序或传输协议,例如 HTTP、SMTP 等来发送 SOAP 消息,这些程序或协议可能会有一些安全模型,从非常高级的模型到根本什么模型都没有。因此,Web 服务应用程序需要一个全面的安全性架构,能适用于所有类型的传输协议。
  • 可能有一些合法的中介需要访问甚至修改部分或整个 SOAP 消息。因此安全性模型必须足够全面,从而可以允许这些中介。

下面的部分定义了 Web 服务安全性的各个方面,他们可以应用于 在普及应用程序中使用 SOA中所描述的应用程序类型。

Web 服务安全性指导方针

W3C Web 服务体系结构需求概述了全面安全性架构的六个重要的安全性考虑:

  • 认证保证任何有认证身份的人都可以访问服务。
  • 授权保证通过认证的人有权访问服务或数据。
  • 机密性保证请求方和提供方之间传输的数据不会被窃听者窃取。
  • 完整性使消息从请求方到提供方这条传输通道上不会被修改。
  • 不可抵赖保证消息的发送者不能否认他/她稍后会及时发送消息。
  • 可访问性确保服务一直是可用的,并且不会被拒绝服务 (denial-of-service,DoS) 这样的攻击所削弱,无论是从托管服务系统的外部还是内部进行攻击。

如今的 Web 服务安全性

Web 服务安全性还处在不成熟的阶段。不断地有新的标准和应用程序被开发和应用。如今,可以从两个层面实现 Web 服务安全性:

  1. 传输层:传输层的安全性利用传输技术的内置安全特性,例如 HTTP、IBM WebSphere MQSeries、IBM Websphere Everyplace Connection Manager 等等。
  2. SOAP 或通讯层:目前正在广泛研究该层以及例如 OASIS 这样的安全性小组所开发的规范。这一层以及 XML 文档层的安全性包括使用数字签名、证书等等。

用 HTTP 保护 Web 服务

可以用下列方法保护通过 HTTP 传输的 Web 服务事务:

  • HTTP 基本授权
  • 带安全套接层 (SSL) 的 HTTP
  • HTTP 基本授权 + HTTPS

但是,HTTP 安全性没有涉及到前面所描述的整个 Web 服务安全性指导方针。最好的可能配置是使用带 HTTP 基本授权的 HTTPS,这样的 HTTPS 涉及到了 Web 服务安全性中除不可抵赖和可访问性之外其余的所有方面。

HTTP 基本授权:基本授权 (BASIC-AUTH) 是 HTTP 中所使用的一种简单的机制。使用该机制,可以防止未授权用户访问 Web 资源。要使用 HTTP BASIC-AUTH 访问受保护的资源,用户需要提供用户名和密码。Web 站点系统管理员用一列合法的用户和用户可以访问的资源来配置 Web 服务器。因为通过 HTTP 调用 Web 服务和访问端点 URL 是类似的,所有可以利用 BASIC-AUTH 限制 Web 服务访问。

HTTP 安全 (HTTPS):安全套接层 (SSL) 是一种允许 Web 浏览器和 Web 服务器通过安全连接进行通信的技术。也就是说,发送的数据由一方加密,在处理之前由另一方来传输和解密。这是一种双向的过程,即在发送数据之前,服务器和浏览器都要对所有的传输进行加密。

HTTP 基本授权 + HTTP 安全:为 Web 服务事务提供了极好的安全性。它还通过签名证书为用户提供了授权机制。但是,如果复制的证书也可用,那么任何人都可以充当代理。因此,安全性的最佳形式是结合使用 HTTP BASIC-AUTH 和 HTTPS。这既满足了 Web 服务安全性前四个方面的要求,又为防止抵赖提供了更好的保护。在接下来的部分中,我们将说明如何配置 Web 服务应用程序来利用这种安全性方法。







在普及应用程序中使用 SOA

本文剩下的部分描述了如何用 SOA 和 Web 服务为关键普及应用程序类型提供公用接口。对于关键普及应用程序,我们主要关心的是:通信、事务、设备管理、同步、基于位置的服务、数据管理以及多媒体服务。为了帮助说明如何在这些应用程序中使用 SOA 和 Web 服务,我们将以一个财政服务为例。该案例是基于下列体系结构的:


图 4. 常见的财政门户体系结构
常见的财政门户体系结构

财政服务案例概述

下面的图表演示了这里所描述的财政服务案例:

  1. 新银行客户通过膝上型电脑签约在线银行,包括例如欺骗发现警告、有新的产品和在线帐单付款之类的服务。
  2. 客户决定检查帐户余额情况(使用膝上型电脑或智能设备)。
  3. 然后客户决定进行在线付款(使用膝上型电脑或智能设备)。
  4. 客户收到一个警告,说已经从帐户中提取大量的金额。警告使客户得以响应,并通过通讯或语音与银行服务代理进行交谈。
  5. 客户在他们的普及设备上使用银行的 Web 服务客户端在线处理事务。


图 5. 场景 1
场景 1

图 6. 场景 2 和 3
场景 2 和 3

图 7. 场景 4
场景 4

图 8. 场景 5
场景 5

用于通讯的 SOA

通讯的概念包括将消息分散给一组通过许多无线网络和协议进行传输的普及设备。通讯操作的实例范围很广,从广播型,例如新闻、股票报价和事件通知到个人通信型,例如寻呼机消息和即时传送 (instant messaging,IM)。近来在无线技术,例如短信服务 (Short Message Service,SMS) 和会话发起协议 (Session Initiation Protocol,SIP),领域中的更多进展已经提供了创新解决方案,这些方案利用了 Web 服务的功能。

应用程序需求

  • IM 应用程序的无缝集成:目前在其它的一些专有提供者中存在一组相当支离破碎的 IM 服务提供者,包括 AIM、MSN 和 Yahoo。为了提高可用性和管理需要巩固这些服务。Trillian Pro 已经通过允许用户从单一客户端配置和使用这些服务在桌面应用程序领域中涉及到了这个问题。通过遵循公用接口加强 IM 服务提供者这一原则在普及环境中也可以工作得很好。
  • 会话管理:新近完成的 SIP 规范促进了 IM 应用程序在移动设备上的开发,代表了流行桌面 IM 应用程序和无线 SMS 系统的融合。SIP 提供会话管理支持,允许用户从传统的请求和响应对象中存储和检索数据,这些对象实际上跨越了多个 SIP 请求。有关详细信息请参阅 JSR 180
  • 保证传送:如今很多 IM 应用程序不能保证消息的传送,他们是“发送并忘记”型的。在 IM 会话过程中发送给不可用的用户的消息通常会丢失。虽然这在大多数情况下还是可以接受的,但有时可能需要保证传送高优先级的消息。这无疑会引起更复杂的问题,包括对消息的认可以及排列或高速缓存不被认可的消息,直到用户在线回答。
  • 高级通讯:SMS,EMS,MMS
  • 安全性:参阅 普及运算安全性

如何使用 Web 服务

Web 服务充当了一个公用的、独立于设备的接口,提供者可以从这个接口向已经订阅的客户端发布他们的服务。该接口也可能直接由客户端或其它的服务调用。这个特性允许使用上面提到的 IM 集线器,在 IM 集线器中可以将各种专有 IM 服务提供者合并为一个客户端应用程序。对于桌面应用程序领域,这样可以提高管理的可用性和易用性。Web 服务通过调用可发现的接口满足客户端的需要竭力提取后端处理同样重要。

最基本的解决方案由一个连接到设备的胖的、客户编写的 Web 服务客户端组成。虽然开发这种方法需要更多的时间和精力,但是由于通过应用程序控制和表示细节给予了客户端详尽的责任使得该方法具有更大的灵活性。而且,各方面通常由容器来处理,包括安全性和会话管理,所以不需要涉及这些问题。

您应该注意到虽然 Web 服务技术对于桌面应用程序和企业应用程序已经很成熟了,但是还需要考虑很多额外的问题使其能适应普及设备在容量上有限这样的局限性。例如,解析 XML/SOAP 消息就需要相当集中,尤其需要考虑处理能力。为缓和这一点, JSR 172规范将提供一个对应于 J2SE/J2EE 的更“瘦”版本。有关详细信息请参阅 J2ME 和 Web 服务


图 9. 胖客户端环境
胖客户端环境

通过允许较小的处理能力或内存,从客户端提取后端处理增加了可用设备的实际数量。如果假设客户端支持对 Web 接口的访问,即通过 TCP/IP 进行通信,那么合并 portlet 集和 WebSphere Portal Server (Portal) 将是一个完美的解决方案,如下所述。通常,客户编写的 portlet 以及专门的可复用 Java servlet 能组成门户页面上的定义区,并且能访问很多不同的应用程序、服务和 Web 内容。Portal 支持对 Web 服务后端 porlet 的部署。这使关注由 Portal 所处理的管理的开发人员自由了,并且允许开发人员将重心转移到实现特定业务逻辑上。 有关实现的详细信息请参阅 创建自己的 portlet 和 Web 服务利用 Web 服务从远程系统中获取数据来开发 portlet


图 10. WebSphere EveryPlace Connection Manager 和 Portal Server 环境
WebSphere EveryPlace Connection Manager 和 Portal Server 环境

WebSphere EveryPlace Connection Manager (Connection Manager) 充当了客户端设备和 WebSphere EveryPlace Access 服务器间的可选传输通道。Connection Manager 允许从后端应用程序中提取低层的详细信息,例如无线协议,因此产生了复用和分离关注点。

Connection Manager 的通讯服务装备启用 Web 应用服务器与前面提到的那些普及设备进行交互。虽然通讯服务支持更流行的 SMS 和不被认可的 WAP 推传送,但是它还启用了很多其它的消息模式,包括通过专有网络传送短信、通过 SMTP 和 SNPP 发送邮件。有关详细信息请参阅 IBM WebSphere Everyplace Connection Manager 版本 5 手册

Everyplace Access 充当了移动客户端和企业环境之间的连接。Everyplace 客户端,作为 Everyplace Access 的一个核心产品,充当了一个附属软件包,提供了带更健壮设备环境的各种 PDA。它提供了取出即可用(out-of-the-box)的 IM 服务,但是,目前还只局限于 Lotus Sametime。

Everyplace Access 的另一个高级特性是智能通知服务 (Intelligent Notification Services,INS)。该服务在订阅通知应用程序和触发器的基础上让企业自动通知移动用户。这是由 Everyplace Access 系统管理完成的,在系统管理中,用户指定信息源、通知标准以及一些爱好和订阅设置。更多详细信息请参阅 WebSphere Everyplace Access 版本 4.3 开发人员手册


图 11. Portal 环境
Portal 环境

因为 Portal 被评价为是一个高可配置的、被认可的架构,因此可以利用它的很多内置功能来减少开发时间和费用。Portal 结合 Everyplace Access 通过用任何标记语言生成页面来支持移动设备,包括用于 WAP 的官方支持的 WML。请求一个页面时,Portal 处理后端流程来自动检测设备类型并以适当的标记语言返回呈现页面内容的 portlet。

财政服务案例中的通讯

在财政服务案例中,通讯为用户带来了更多特性和便利。例如,可以将系统基础架构设置为当检测到可疑的帐户活动时,例如提取大量资金,警告用户。正如上面所提到的,Everyplace Access 的 INS 支持基于订阅的通知,在这种通知中,消息由用户订阅的特定事件触发。

然后用户可以通过 IM 应用程序选择连接代理并进行通信来解决问题。由于会话的本性和重要性,可能将消息作为保证传送,一直保留直到客户端认可该消息。

用于事务服务的 SOA

考虑普及环境中的事务时,必须要考虑到普及环境强加在事务上的限制能够执行。而且,由于普及环境能包含不同功能的任意数量的不同设备,所以有必要考虑如何用相同的事务来服务不同的设备和他们的功能。

对于这个问题,最明显的回答是从客户端提取事务普通的详细信息。有两种方法可以实现这一点。其一是使抽象层完全不知道哪些客户端访问了它。这需要客户端足够智能化,能捕捉并显示适当的数据。很明显,这指的是胖客户端,胖客户端能使服务面向多种客户端,但是对每个客户端可能有较高的 CPU 和内存需求。

使抽象层足够智能化的另一个方法是区分请求它的服务的客户端的不同功能。在这种情况下,每种设备的不同功能的详细信息必须由服务提供者来说明。客户端将被看作一种提供低 CPU 和内存需求的瘦客户端,但是需要受服务提供者支持的有限数量的设备。

Web 服务和 SOA 能涉及提供简单的抽象层还是智能抽象层之类的问题。下面的部分演示了这种 Web 服务如何提供所述功能。

应用程序需求

普及环境中的事务服务同样需要考虑传统应用程序中的事务问题,以及客户端能运行在几个不同类型的有着不同功能的硬件和软件环境中。同样的,设备可以放在任何地方,并且由于要在给定的环境中显示信息,所以必须要注意其类型问题。下面的列表并没有准备详尽列出潜在的需要考虑的地方,但是考虑普及环境中事务的实现需要一个合理的开端:

  1. 由于设备只能显示一定数量的结果,因此用户可能需要在服务器端缓存一些会话。
  2. 在服务器端将事务合并为几个集合调用,从而减少通过宝贵的低无线带宽传输的网络调用。
  3. 让服务器端执行一些复杂的排序或其它的 CPU 密集型操作。
  4. 同步和异步事务之间的区别。如何实现这两类事务?
  5. 在线和离线事务。
  6. 关键是要最大限度使用有限的在线时间。尽量最少时间,因为设备需要等待结果。这样可以减少在线费用。
  7. 发送并忘记事务。排队等候代表设备的作业。然后当设备反方向检查时,就能得到结果。
  8. 安全性更容易受到威胁。基于显示在这些设备上的信息种类问题,需要特别关注。例如,银行型的事务可能允许主用户修改他们的帐户信息,但是用无线通信进行相同的事务可能不允许编辑功能,只有查看功能。

如何使用 Web 服务

在普及环境中有两层可以使用 Web 服务。一是在远程设备上实现 Web 服务客户端,这样将直接调用 Web 服务。该方法如下所示:


图 12. 使用 Web 服务胖客户端模型的普及事务
使用 Web 服务胖客户端模型的普及事务

这个案例的好处是远程设备已经完全控制了如何显示数据。设备将知道它自己的局限性并以适合于那台设备的方式显示返回的数据。

这个方法还有一个好处,即允许嵌入式程序对事务进行优化。这是通过允许设备存储大量的事务直到它认为在时间上适于发送或请求数据实现的。适当的时间可以由排队等候的事务总量决定,或者在普及环境中网络可能断断续续的可用,因此可以一直保存事务直到网络可用。

在这里,SOA 还有一个好处,即客户端不需要担心调用事务的任何详细情况。客户端不需要担心数据库连接、特定的协议、专有数据格式以及不断变化的后端系统。它所需要做的是构建 XML 并利用 Web 服务客户端发送数据。因为这些都是开放的标准,所有能创建各种设备都能支持的单独事务。Web 服务提供者不需要编写特定的代码来支持不同的设备。这也从根本上普及了事务本身,从而通过允许在各种不同设备的服务提供者间共享中央逻辑促进不同设备间数据的一致性。

财政服务案例中的事务服务

要继续银行实例,我们先来看一下用户想用手持 PDA 设备在线购买商品的情况。那个设备可能有一个内置的客户端,可以查找从银行请求临时信用卡数量的 Web 服务事务。客户端然后可以使用这个信息来填充商品的购买信息。同样地,智能电话也可以用于运行同样的 Web 服务事务,但这时购买一罐苏打水的信息可能是被传送到自动售货机的。因为有些 Web 服务客户端可以运行在任何设备上,一个事务也可以供多个设备所用。

用于设备管理的 SOA

随着无线设备的数量到 2006 年将达到 11,100,000, 设备管理也变得越发困难。而且,由于多媒体性能和带宽问题不断的严重,通过这些设备运行的应用程序的复杂性也无疑会增加。为了通过被部署的应用程序进行维护控制,必须要管理所有这些设备。

可以迅速的将新的特性和功能添加到移动设备中。因此,最新的、高级移动设备中的设备罢免和软硬件的更新也变得越来越常见,多得让网络操作人员也感到吃惊。

应用程序需求

和一直围绕着 LAN 和受后端防火墙保护的 PC 和服务器不同,无线设备,例如智能电话、PDA 甚至很多主流移动电话在本质上来说更难管理。他们通常既充当运营工具又充当私人生产性设备,并且很容易丢失或损坏,而且换代非常频繁。因此,CIO 和网络操作人员必须要认识到移动设备常遭受设备管理上下文中规则的不同设置。下面列出了一些关于设备管理应用程序 人们想要的功能:

  1. 通过无线网络 (OTA,Over The Air) 向设备发送升级包
  2. 存储、管理和提供软件映象
  3. 驻留在移动设备上的客户端
  4. 软件部署
  5. 资源和配置管理
  6. 故障管理
  7. 设备控制和数据安全性
  8. 备份和恢复

主要区别是在移动设备上进行实现自我诊断和自我处理的能力,通过无线网络与客户端软件协同工作的集中管理的、基于 Web 的控制台,以及以带宽和网络连接为基础进行更新的智能传送。

如何使用 Web 服务

在这个案例中,设备系统管理员通过 Web 服务接口调用对所有设备的更新处理。Web 服务接口允许对任何能用 Web 浏览器查找设备管理服务器的客户端的管理。更重要的是,它在所有不同设备的专有管理接口间添加了一个抽象层,允许用一个统一的接口管理所有的设备。下图演示了这种思想:


图 13. 通过 Web 服务和专有接口进行设备管理
通过 Web 服务和专有接口进行设备管理

通过 Web 服务提供设备管理的另一个好处是能从单一集中的位置管理包含在安全环境内的设备。所有要做的是让每个单独的位置包含一个启用了 Web 应用服务器的 Web 服务,例如 WebSphere Portal Server 5.1,并通过防火墙访问端口 80 和 443。这种情形尤其适于两种情况:一是可能不能从公司内联网访问远程办公室,二是远程办公室位于内联网中的安全子网内部。下面的图表描述了这种情形:


图 14. 设备管理体系结构
设备管理体系结构

另一个要考虑的设备管理情形是在设备意识到它需要更新的情况下。有人可能允许专有设备接口直接由远程设备调用。但是,这可能有很重要的含意,假设有很多不同的设备类型,并且每种都需要封装自己的专有设备接口。这些设备接口中的每一个都必须按照企业的需要来确保他们的安全。只有一个 Web 服务供设备调用可能要更容易一些。每个设备都将传送企业所需的适当的安全性证书请求。经过验证和认证后,Web 服务将调用适当的专有设备接口来发送必需的更新。

财政服务案例中的设备管理

回到我们的银行实例中,假设有一个包含银行应用程序的 PDA。当 PDA 运行银行应用程序时,它首先调用一个 Web 服务,检索最新的软件版本列表。设备用一列当前安装的软件和认为余额应用程序需要更新的通知与这个列表匹配。然后设备调用软件来更新 Web 服务和安全性证书以及为标识它自身所需的信息和需要下载的软件。Web 服务用适当的参数依次查找特定于 PDA 的软件更新设备接口,从而标识设备并找出需要部署到那个设备的软件的位置。在该实例中,Web 服务就设备和专有设备更新软件间的安全性提供了一个抽象层,并指出了关于如何管理以及在哪里管理可部署的软件。每种设备都调用相同的 Web 服务,因此企业不会受到安全性或软件版本的干扰,并且管理计划也是由专有设备接口提供的。

用于基于位置服务的 SOA

基于位置的服务 (Location-based services,LBS) 是为用户提供定制内容的通道。全球定位卫星 (Global Positioning Satellite,GPS) 系统是一个提供准确用户三角位置的测量机制。这样的系统需要普及组件设备提供更多的功能。并不是所有的设备都有这样的功能,因此必须通过用户基本信息和用户输入来提供 LBS。最初的检查可以通过 IP 路由和发现用户的可能位置进行管理。

客户端应用程序需要提供通过 Web 服务向服务器发送信息的功能,从而为客户端提供内容,这些内容用户可以使用。由于服务器知道用户的位置,所以它可以向客户端发送例如以用户当前 GPS 位置为基础的本地信息之类的数据。

应用程序需求

  • 运行在设备上的客户端应用程序
  • 允许设备定位的可选 GPS 硬件
  • 用于设备定位的可选用户输入或配置设置

如何使用 Web 服务

在客户层使用 Web 服务允许在用户指定位置的基础上按需发现和传送内容。Everyplace Access 服务器还有额外的功能,例如内部 UDDI 发现。尽管没有预封装产品也可以提供开发和功能,但是使用 Everyplace Access 可以节省时间。

考虑到普及运算的本性,LBS 必须和其它的服务一起使用,来决定是否以用户设备为基础将指定内容传送给用户。为了将内容传送给指定的普及设备必须进行代码转换。例如 Everyplace Access 服务器这样的预封装产品有预先定义的针对各种设备的代码转换模板。所有的片段都能从头进行开发,但是正如前面所提到的,这样将需要更多的时间和精力。在设计和开发的过程中,SOA 允许公用 API 和函数提供帮助。

Everyplace Access 服务器提供了很多用于实现 LBS 的工具。Everyplace Access 中的 知道位置的服务 实现了知道位置的应用程序的快速开发和部署。为了支持知道位置的服务,Everyplace Access 提供的 API 使开发人员以标准的方式添加知道位置的 portlet。服务适配器必须由各个服务提供者编写,从而允许在知道位置的环境中提供服务。服务适配器可以扮演很多角色,例如接口转换、服务调用和错误处理以及带服务提供者的身份验证。根据 Everyplace Access 提供的知道位置的服务 API 所编写的服务能够处理通常的身份认证和其它特性,不需要开发人员对那些公用片段进行改写。

用于 LBS 的自动售货机案例

在快餐店自动售货机实例中,普及设备以其位置为基础,可以通过 Web 服务连接邻近的服务提供者,并获得一列可用的自动售货机及其内容。邻近的服务提供者可以由内容浏览应用程序来提供,这些内容浏览应用程序接受用于用户位置的用户输入,或由客户端应用程序提供,客户端应用程序足够智能化能发现邻近的服务提供者并查询可用的服务。然后用户能够通过浏览可用商品,并用他们希望的商品继续执行自动售货机。购买业务也可以在设备上进行,如果这项特性可用的话。服务提供方可能会列出区域周围可用的其它服务,例如本地地图、商店以及更多。有了多种独特的客户端设备和 Everyplace Access 服务器提供的带援助的知道位置的服务,就可以定义公用服务了。Everyplace Access 服务器能处理很多常见步骤,例如认证和事务处理。如果不能处理,它会将请求向前传送给能处理请求的服务。

财政服务案例中的 LBS

在我们的财政服务案例中,用户能以他们当前的位置为基础签名,他们当前的位置是用户输入的或由 LBS 决定的。可能已经安装了客户端应用程序和设备,因此可以与服务提供者进行无缝通信。信息可以通过 Web 服务发送并以他们的位置为基础及时向用户提供必需的信息。Web 服务可以用于传输客户端和服务提供者之间的数据,但是基于用户的当前位置,并不是所有的服务都可以。例如,如果用户在加油站,他们可能只能选择财政服务案例中的选项 2,该选项是用来检查用户帐户余额的。这可以结合用户位置、用户对应用程序的预配置设置或各种其它可能的案例来确定。这也可能是由于位置缺少服务或要冒安全危险而造成的。在几个街区之外的别的位置中,相同的用户可能能执行前面提到的所有情形。有关实例请参阅图 15:


图 15. 基于位置的案例
基于位置的案例

Everyplace Access 与 Portal Server 一起能提供例如身份验证这样的功能,但是,如果有必要它也能单独实现。

用于同步服务的 SOA

同步服务可以让用户同步发送邮件、PIM 数据以及常用数据。设备上需要有客户端来同步发送数据。使用 SOA 能允许通过 Web 服务以常用方式传送客户端和服务器之间的数据。从普及运算的角度来看,数据传送必须考虑客户端的性能,例如处理数据的能力、存储量和带宽。

设备在尺寸上可以不尽相同,这就带来同步数据必须能适合各种类型的设备,包括进行代码转换向客户端设备提供内容。Everyplace Access 服务器用大型邮件服务器提供了同步发送邮件和 PIM 数据的功能。有了 SOA 和标准,就可以扩展这样的 Web 服务,从而为能解析这样数据的任意类型的客户端提供同步服务。

应用程序需求

  • 能够提供同步服务和为用户提供有用信息的客户端应用程序
  • 带各种存储介质的数据存储机制
  • 确保数据合法性的数据完整性 (CRC) 机制

如何使用 Web 服务

LBS 还可以通过启用应用程序来确定用户的位置,然后以那个位置为基础同步传送特定的数据来帮助数据的同步传送。Web 服务发现还可以用于帮助查找提供所需数据的同步服务提供者。在公司内部使用同步服务非常重要,因为这样可以允许用户在公司内依靠用户的位置同步传送所需的数据。使用 SOA 和 Web 服务的常用方面的好处在于他们允许同步传送无限多的数据。常用的弊端是需要更长的开发时间,这是由于很多方面都没有定义而造成的。有关实例请参阅图 16:


图 16. 公司内部的数据同步
公司内部的数据同步

假设用户从大型商店部门出发,并希望同步发送数据,那么详细信息也会同步发送。假设用户进入了财政部并决定同步发送数据,那么财政数据也将同步发送。

在大型商店购物中心实例中,通常,大型商店结算过程需要预扫描商品,虽然会员们正在排队等候。商品在无线普及设备上进行预扫描。会员登记时,收银机服务员扫描会员的会员卡。一旦卡被扫描,系统就能拖出所有的预扫描商品,事务很快就能完成。这加快了结算过程,因为不需要在购物车间转移商品。SOA 为无线设备和结算登记都提供了公用接口。即使大型商店有时突然决定要更新或更换设备,但是接口保持不变,而且还可能减少实现费用。

财政服务案例中的同步服务

用户的设备可能有一个私人资金管理应用程序,这样用户就应该和他们的银行提供者同步。Web 服务实现能提供同步发送用户银行信息的公用方法,无论是否要发送信息类型。如果用户检查他们的余额,会给他们提供一个选项,可以将数据下载到设备上。以客户端设备为基础,服务提供者能确定同步传输数据的数量。用户还可以在客户端设备上准备离线付款,并且稍后和服务提供者一起同步进行,最后当数据同步发送后,事务完成。客户端应用程序还可以连接其它的实现了相同体系结构和数据传输/通讯方法的财政服务提供者。

用于媒体应用程序的 SOA

媒体应用程序特指音频/视频流和或回放。这些类型的应用程序可以用于员工培训和身份验证甚至是新闻和基于信息的服务。媒体应用程序主要关注的是客户端设备能够按照指定的媒体格式解码和回放。已经有很多带各种硬件规范的无线设备。为了支持用于媒体应用程序的所有这些设备,我们需要了解哪些类型的媒体格式可以形成流或甚至回放。Web 服务复用的完美实例是使用设备管理服务处理大多数设备。我们还必须考虑用什么协议来支持媒体格式的传输。例如,如果有一个商业案例需要视频/音频回放,我们可以安全地假设作为一种客户端设备上的传输方式 SMS 消息将不被支持。

应用程序需求

  • 客户端设备上的高处理能力
  • 支持流的客户端设备
  • 支持媒体格式回放

如何使用 Web 服务

下图演示了如何在瘦客户端设计中使用 Web 服务:


图 17. 瘦客户端设计
瘦客户端设计

在瘦客户端设计(也称为客户端/服务器端设计)中,开发人员可以假设他们支持能访问 web 接口的客户端设备,例如浏览器,因此允许他们查看 http 请求并能回放 Real Network、Quicktime、Media Player 甚至 Macromedia Flash 媒体格式。有了这个解决办法,开发人员就不用担心设备支持哪些协议,只需要服务提供者允许访问因特网即可。

对于瘦客户端设计,多数实现是由服务器端的代码处理的,检测客户端设备的性能并决定用什么格式形成流甚至下载到设备上供回放。可以发现,这个解决方案与为桌面应用程序架构 Web 应用程序的客户端/服务器端方法没有什么不同,这是因为开发人员还需要考虑客户端的性能。唯一的区别是现在包括了对小型存储设备的额外检查。

这些瘦客户端设计中的服务器端应用程序可以是自产的,可以运行在任意的应用服务器上。记住,定制应用程序将延长开发时间并需要长期的维护费用。IBM 提供了作为 Portal Server 一部分的替代解决方案。Portal Server 已经有一个被业界认可的架构,该架构易于扩展用来支持额外的设备和容量,并有一些受支持的现成的 (out of the box) 设备。Portal Server 能否允许客户修饰编写的 portlet 取决于客户端是否有这方面的请求。自产的解决方案还必须提供认证、授权、报告等等之类的功能。

在 SOA 中,定制实现和 Portal Server 都能利用 Web 服务来封装媒体应用程序和利用现有的 Web 服务。然后,可以将其用于实现推模式设计,在这种设计中,Web 服务自己调用客户端设备上的命令,从执行程序或想要发送广播或目标消息的管理程序将公司广播形成流。另外,我们可以使用订阅和基于位置的服务来跟踪设备。

下图演示了一个样本胖客户端设计:


图 18. 胖客户端设计
胖客户端设计

胖客户端设计增加了更多复杂性,例如需要一些其它的胖客户端体系结构。有了胖客户端,设备就能分解和组装 Web 服务消息了。胖客户端设计限制了能受支持设备的数量,这是由于目前在北美市场上设备性能有限。和任何其它应用程序类型类似,胖客户端设计可以使用设备专有接口。缺点是需要在设备和应用服务器间安放相同类型的传输通道。

和瘦客户端设计不同,在胖客户端设计中,客户端设备和服务器端(WebSphere Application Server 或 Portal Server)都需要实现。架构客户端实现使开发人员可以选择使用设备专有接口或调用 Web 服务从非专有设备编码中得到好处。在媒体应用程序实例中,两种解决方案都是可行的,因为第一个选项可以使用 SMS 通过 MMS 来请求要发送的媒体。

正如上面所提到的,例如 SMS 或 MMS 这样的解决方案需要在客户端设备和应用服务器间安放象 Connection Manager 这样的传输通道。有了 Web 服务,就不需要 Connection Manager 和对 SMS 和 MMS 的专有调用了,取而代之的是一个能与支持 Web 服务消息的其它设备进行通信的普通接口。

财政服务案例中的媒体应用程序

在财政服务案例中,可以利用媒体应用程序来支持想为其用户和客户提供无能服务的客户端。胖客户端实现可以用于通过 Web 服务封装基于事务服务传输的 VoiceXML,从而处理银行事务。

用于数据管理应用程序的 SOA

为了向客户提供适时信息,数据管理应用程序控制、保护并促进了数据的访问。这些功能都是由数据库管理系统提供的。

应用程序需求

  • 针对瘦客户端解决方案的客户端设备上的 Web 接口
  • 针对胖客户端解决方案的 SQL 客户端
  • 常用数据的获取、验证、处理、存储、检索和显示界面

如何使用 Web 服务

在瘦客户端模型中,通过 Web 接口可以促进服务器端的数据管理服务。如今这种设计与典型的 web 应用程序不再有很多区别,尽管 Web 服务设计可以利用基于事务的服务和基于同步的服务执行提交和回滚来保持数据是准确和最新的。对于瘦客户端设计,实现都是在服务器端进行的。

用于数据管理服务的胖客户端设计有两种解决方案。和任何其它胖客户端解决方案一样,Web 服务的便携性和可复用性使其成为最简单的解决方案。第二种解决方案需要在客户端设备和应用服务器间安放一个工具,用于将设备上的指令进行代码转换从而传送给应用服务器上的服务。

Web 服务设计还允许体系结构在数据管理实现能驻留在客户端设备上这方面的灵活性,允许其访问上面提到的其它服务来帮助促进作为数据管理包的一部分的事务和同步性。另一个可能的解决方案是将数据管理服务当作 Web 服务自身来实现,因此其它的需要数据管理的服务都能使用。

第二种设计要求将 DB2® Everyplace 安放在客户端设备和应用服务器间,从而方便数据管理。有了 DB2 Everyplace,就能构建使数据管理随处可用的 PDA 应用程序了。您的应用程序可以连接常见的 PDA,例如 Palm TM、Handspring TM、HP® Jornada、Cassiopiea TM以及 Compaq iPAQ TM 设备。DB2 Everyplace 还支持基于 EPOC 的 PDA 和带内嵌 Linux 的设备。

财政服务案例中的数据管理

数据管理服务可以作为财政服务开发中的一个辅助工具。允许财政指令的灵活性是在客户端还是服务器端实现依赖于安全性、数据的准确性以及其它需求,从而将数据管理封装为 Web 服务既利于瘦客户端设计又利用胖客户端设计。如果使用数据管理服务是应用程序设计的中心,那么数据的分析和报告会更准确。







结束语

本文描述了如何在普遍环境中利用 SOA 为使用 Web 服务提供简明的解决方案。本文描述了各种应用程序类型,在设计解决方案中可以使用这些类型。我们用一个财政服务样本演示了如何在特定的情形下实现特殊的服务。最后,描述了能够帮助使 Web 服务更便于使用的工具,例如用于应用程序的基础设施安全性和可扩展性的网关或代理装置。







附录:J2ME 和 Web 服务

就目前的情况而言,在面向服务的体系结构 (SOA) 环境中,还没有标准和有效的机制供启用了 J2ME 的设备利用 Web 服务技术。虽然已经详细定义了用于 J2SE 和 J2EE 领域的 Web 服务规范,但是没有涉及到 J2ME 领域中的额外限制问题。这些限制包括要求 Web 服务技术符合平台性能和容量要求。更明确的讲,必须在运行时内存和处理需求内执行 API,并且要满足目标设备的内存要求。此外,还必须考虑到部署环境的局限性,包括低带宽和高延迟。

来自 Java Community Process Program 的 JSR 172试图通过引入两个附加包来涉及这些问题,这样将能在启用了 J2ME 的设备上实现 Web 服务技术。因为 XML 是消息格式的实际标准,所以即将引入的附加包主要负责优化 JAXP 和 JAX-RPC。

JAXP 为操作结构化的 XML 数据提供了必需的基本的 API。J2ME 版将包含一个为 J2SE 和 J2EE 平台而定义的严格的子集。它将通过只支持起决定性的功能实现这一点,包括 SAX 解析以及对 XML 名域空间、UTF-8 和 UTF-16 编码的支持。包括 XSLT 和其他 XML 解析的变体——如 DOM,将不被支持。之所以不支持 DOM,是由于它的实现容量和运行时的内存占用问题。

JAX-RPC 为实现来自 J2ME 基于 XML 的 RPC 通信提供了 API 和规定。再一次将它与 J2SE 和 J2EE 中的对应版本相比,可以看出不支持 SOAP 1.1 编码,扩展类型映射和服务端点能使 JAX-RPC 得以优化。

JSR 规范,加上这种功能受限设备的最佳实践设计模式,到底会产生什么样的效果呢?本部分主要集中讨论概念层次的问题,所有省略了实现细节。有关下列模式的进一步描述和实现细节,请参阅 James Noble、Charles Weir 和 Duane Bibby 撰写的 小型存储软件:存储受限系统的模式

Web 服务客户端案例

SAAJ

客户端通过 SAAJ 与 Web 服务通信包括几个过程。首先,它必须程式化的创建一个消息,并依照 DTD 强制规定的预定义格式添加内容。然后,获得一个 SOAPConnection 对象,发送消息,收到响应消息后阻塞。

  • 处理:打包:将应用分成包,只有当需要某个包时,才加载它。
  • DTD:资源文件:在二级存储器中保存配置数据,根据需要加载和释放数据条目。
  • 连接工具:只读存储器:在只读存储器中保存只读代码和数据。
  • 响应消息:数据文件:每次处理少量的数据,把其余的保存在二级存储器中。压缩数据:在结构内部压缩数据条目,以使它们占用最小的空间。

JAXR

同预定的方案(如在 SAAJ 中)相比,客户端可以选择向 Java WSDP 注册服务器 (Java WSDP Registry Server searching) 动态发送查询请求,通过 JAXR 查询支持 JAX-RPC 的 Web 服务。它必须首先通过查找连接工厂建立一个连接,设置连接属性,获得 RegistryServiceObject 对象。利用 RegistryServiceObject 对象,然后客户端能够用相应的 BusinessQueryManager 方法进行查询,例如 findOrganizations、findServices 和 findServiceBindings。这些方法返回 BulkResponse——一个对象集。要想进行优化,客户端可以选择缓存和创建一个发行人的本地数据库。

  • 处理:打包:将应用分成包,只有当需要某个包时,才加载它。
  • 连接工具:只读存储器:在只读存储器中保存只读代码和数据。
  • BulkResponse:数据文件:数据文件:每次处理少量的数据,把其余的保存在二级存储器中。压缩数据:在结构内部压缩数据条目,以使它们占用最小的空间。
  • 缓存:共享:一次保存数据,在任何需要的地方共享。

JAX-RPC

一旦通过 JAXR 构建了相关的 Web 服务资源库,客户端就能够通过 JAX-RPC 执行业务逻辑。实现此功能的方法之一是创建静态存根或动态代理。更常见的是,结果以 Java Bean 集返回。以前,客户端首先创建存根对象,设置存根的端点地址来访问特殊的服务,并且向服务器端点接口投掷存根。

创建动态代理时,客户端创建一个服务对象,该服务对象带有一个 ServiceFactory 和两个参数:WSDL 文件的 URL 地址 和 Qname(受 XML 限制的名称)。然后创建一个服务端点接口型的代理。

  • 处理:打包:将程序分成包,只有当需要某个包时,才加载它。
  • 存根/代理工具:只读存储器:在只读存储器中保存只读代码和数据。
  • 参数/结果集:数据文件:数据文件:每次处理少量的数据,把其余的保存在二级存储器中。压缩数据:在结构内部压缩数据条目,以使它们占用最小的空间。

通用 J2ME 应用程序设计模式

  • JavaBeans:
    • 压缩数据:在结构内部压缩数据条目,以使它们占用最小的空间。
  • 接口:
    • 小型接口:设计接口让客户端控制数据传输。
  • 属性文件:
    • 资源文件:在二级存储器中保存配置数据,根据需要加载和释放条目。
  • 内存使用情况:
    • 应用程序转换:将您的系统分为独立的执行部分,一次只执行其中的一个。
    • 内存限制:为每个组件限制它能够使用的最大内存,当超过界限时择存储单元分配失败。
    • Captain Oates:宁可为不太重要的组件牺牲内存,也不能让重要的任务出现故障。
    • 局部故障:确保内存溢出时,系统总是处于安全状态。
    • 存储单元分配池:对于类似对象,预分配一个对象池,并回收无用的对象。
  • 存储器:
    • 压缩数据:在结构内部压缩数据条目,以使它们占用最小的空间。
    • 压缩:在内存中移动对象,来移除它们之间无用的空间。
    • 自适应压缩算法。

posted @ 2006-04-17 02:52 wsdfsdf 阅读(171) | 评论 (0)编辑 收藏

改进您的 SOA 项目规划-----用健全的治理原则确保项目的成功实现

面向服务体系结构(Service-Oriented Architecture,SOA)具有显著提高 IT 效率的潜力。但是要在组织中实现它,仅仅了解技术是不够的,还必须精通管理。在本文中,Yvonne Balzer 会描述能帮助您成功实现任何 SOA 项目的治理原则。

如今,业务和 IT 价值链开始在行业中融合。我们现在所说的 企业体系结构面向服务体系结构(SOA) 都与 IT 的实现无关。因此,我们也需要建立业务和 IT 之间的横向联系,定义和开发诸如 SOA 这样的体系结构,并运行专门针对企业的客户端项目。

出于这些原因, 治理在如今的 IT 行业中的角色变得比以前更为重要。在本文中,我将介绍在 IBM IT Management Consulting (ITMC) 开发组的最佳实践治理方法,这些方法都已在几个客户端项目得以开发和实现。我们将从已经过检验的 IT 治理结构和实践开始,增强治理模式以满足 SOA 的需求。

动机和问题

由于行业中出现的问题和挑战, IT 在现代组织中的角色发生了根本上的变化。现在,IT 必须以接近实时的速度非常迅速的反应并灵活的启用业务。IT 必须设计和管理一部分高度集成的复杂企业体系结构,并且业务和 IT 组件之间的界线也越来越模糊。本文将介绍关键的治理功能,它能够帮助您达到这些目标并成功实现 SOA 项目。

治理提供了一种拱形(overarching)的结构,其目的是为了从战略性、功能性和操作性层次上支持用户的业务目标。它为有效的规划、决策制定、操纵以及 SOA 项目控制而定义了规则、流程、度量和组织结构,以达到用户的业务需求和目标。最后,治理模型定义了以下内容:

  • 需要做 什么
  • 如何去做。
  • 应该由 来做。
  • 应该 如何进行度量。

该模型同样也为有效的规划、决策制定、操纵以及 SOA 项目控制而定义了规则、流程、度量和组织结构,以达到用户的业务需求和挑战性的目标。

以下是在 SOA 项目内定义适合的治理结构所涉及的一些关键性问题:

  • 客户端从该项目中能获得哪些好处?客户端的目标和期望是什么?
  • 在进行 IT 规划、操纵和决策制定时,有哪些角色、职责、结构和流程是已经存在于客户端站点的?
  • 如何提高技能和领导能力?
  • 需要哪些原则和指导方针来优化业务和 IT 之间的关联?
  • 为了企业和 IT 能够进行交互,以维持一致性并保持足够的灵活性来快速适应新的变化,什么样的构造方式才是适合的?
  • 什么样的服务规范、服务定义和描述才是适合的?
  • 如何控制和度量服务及服务提供者?由谁来对现有服务所进行的修改进行监控、定义并授权?
  • 如何决定服务的原始策略?
  • 存在哪些问题?项目如何支持客户端来解决这些问题?

基于我们的经验,我们相信公认的、正式的治理模型是成功实现业务目标的关键。因此,我们建议在 SOA 项目中建立治理功能。该治理模型应该也处理 渐进式改造的基本需求,即集中使用每个步骤中学习到的内容来定义和执行下一步。创建用于 SOA 的改造和实现的治理程序体,是治理模型的核心需求。为快速可靠的完成该项工作,我们提倡使用客户端现有的结构并共同工作,以改造该结构并使其适应 SOA 项目。







治理模型:SOA 项目的正确形式

IT 治理有一些不同的定义。IT Governance Institute(请参阅 参考资料以获得相关链接) 给出了一个对 IT 治理的较好的一般概述:

IT 治理是指导部门及执行机构的职责。它是企业治理的主要组成部分,由领导阶层和组织结构组成,它确保组织的 IT 能够维持并可以扩展组织 IT 的策略和目标。

IT 治理的目的是指导 IT 以确保它的性能可以满足业务目标,因此:

*IT 和企业的联合会使预期的利益变为现实。
*IT 使企业的机遇得到开拓,并使企业的利益最大化。
*IT 资源能够可靠的使用。
*IT 相关的风险被合理的控制。

图 1 的治理模型是组织结构、连接流程和相关联系的结合。它基于战略方向和被称为 治理原则的公认的基本原则。在大量复杂的项目中,该方法通过我们的经验得到了不断的改进。由此,我们认识到这些要素是任何类型项目的基础。


图 1. 核心治理要素
核心治理要素

战略方向及指导原则

客户端战略方向的定义是成功发展适合的 SOA 及持续专注于业务需求的关键。对业务策略和目标的普遍理解是业务单位和 IT 的基础。

治理的原则和指导方针是任何决策的基础。这些原则和指导方针将规定解决方案的范围并定义协作的方式。因此,执行部门应该很好的理解接受它们。其中一条主要的指导方针就是 治理方式。两种主要方式的区别是:

  • 中央式治理:这对企业而言是最好的方式。治理委员会拥有来自每个服务域(以后对此将有更多介绍)和专家的表述,这些专家可以与实现解决方案关键技术组件的人进行对话。中央治理委员会将在对实现修改授权之前,评审任何对服务的添加、删除以及对现有服务的变更。

  • 分布式治理:这对分布式团队而言是最好的方式。每个业务单元都能够控制在自己的组织内部如何提供服务。这需要功能性的服务域方法。中央委员会可以为不同的团队提供指导方针和规范。

每个原则都应该依照基础理论来定义,这些理论用于说明该原则的目的和含义。指导原则定义了 SOA 的开发、维护和使用的一些基础规则。特定原则用于体系结构设计或是服务定义,也就是说,这些指导原则专注于特定的主题。这些原则具有以下特性,它们能为设计样式提供固有特征,并应该包括项目的以下几个方面:

  • 指导原则:
    • 重用(Reuse)、粒度(granularity)、模块性(composability)、 可组合性(composability)和组件化(componentization)
    • 与标准(一般的或是特定于行业的)一致
    • 服务的识别和归类、提供和传递、监控和跟踪
  • 特定体系结构原则:
    • 封装
    • 业务逻辑和基础技术的分离
    • 单一实现和组件的企业观点(enterprise-view)
    • 机遇存在时利用现有资产
    • 生命周期管理
    • 系统资源的有效使用
    • 服务的成熟度和性能

通过理解体系结构和设计的 SOA 样式的原则,以及这些原则对业务和 IT 的联合所带来的好处,您就能在设计解决方案时确定 SOA 的适用性。这些原则驱动服务设计明确的基本特性。您可以将每一个特性对应到一个或多个提供给原则和特性以完整性的 SOA 原则。

治理流程

治理流程是战略性的 IT 规划和操纵所需的流程,比如:

  • 策略的发展
  • IT 规划
  • 业务量管理
  • 资源
  • 创新管理
  • 体系结构管理。

在 SOA 项目中,需要在项目的一开始就建立 体系结构管理流程(AMP)。 AMP 主要的目标是确保已定义的 SOA 的一致性、有效开发以及持久性。

基于我们在许多项目方面积累的经验,我们开发了一个标准 AMP,您可以在客户端项目内快速简单的使用它。该流程由四个子流程组成,如 图 2所示,这些子流程使用 IBM LOVEM 表示法,定义完善且可用。( LOVEMline of visibility engineering methodology,请参阅 参考资料以获得更多信息)。


图 2. 体系结构管理流程
体系结构管理流程

下面更详细地介绍图中的一些要素:

  • 体系结构的评审及批准流程:
    • 定义构造好的方法来评审和批准现有 SOA 的变化,做出与 SOA 的路线相一致的决策。
    • 设计和服务的正式评估审核是关键的控制点。
  • 体系结构的例外以及渐进发展流程:
    • 提供请求体系结构决策的方法。
    • 允许 SOA 体系结构的例外以满足独特的企业需求。
  • 体系结构维护流程:
    • 当新的服务添加到体系结构中时,确保 SOA 已被维护且修改已经传达到风险承担者。
    • 体系结构的变化都有备有文档说明且被传达。
  • 体系结构通信流程:
    • 确保 SOA 对每个需要访问的人都是可用的。
    • 加深对 SOA 重要性的理解

组织结构

为提供体系结构治理,必须在组织内部确立一些结构,定义所有需要的角色和职责,以及定义适当的制定决策的组织结构。经验显示,建立 体系结构办公室很有用,特别是在复杂且庞大的项目中。体系结构办公室职责是保持 SOA 在战略、战术、操作层次上符合业务需求。该办公室应该包括体系结构设计权威人士,他是体系结构管理流程的所有者。此外,每个层次都定义了角色和职责。

根据我们在客户端所做的工作,有两个有效办法可以用于建立和运行这样的体系结构办公室:

  • 如果客户端组织已经有了和体系结构办公室类似的制度,那么您应该结合这个现有的组织结构。应该确保所有的功能和职责都能够明确的用于制定体系结构决策。对于 SOA 项目,这些功能和职责应该涉及到 SOA 决策,并随时保持联络。
  • 如果客户端站点没有治理委员会,我们推荐您在 SOA 项目的上下文中建立体系结构办公室,并通过它来决定关键的可交付项目。用 SOA 项目中的客户端和项目人员暂时充当该体系结构办公室的工作人员。这些人员应该是决策制定者,并且应该包含 CIO。在项目的最后,体系结构办公室可以被集成到客户端组织。

图 3 说明了体系结构办公室以及每个层次上的角色和职责。在战略层有体系结构部门,它是一个决策部门,负责提交标准和原则,并通过业务和 IT 策略来进行服务的优先级排序。在战术层,体系结构组作为体系结构设计权威来运作,负责定义体系结构管理流程,以及定义修改、删除或添加服务和管理域的决策准则。在操作层,项目组开发和实现服务。


图 3. 体系结构办公室
体系结构办公室

每个项目组都需要角色描述来定义其任务和职责以及操作的模式。

SOA 治理引入 域所有权的概念, 管理一系列共享常用内聚业务的可重用服务。在很多情况下,这些是业务服务的子集,比如用户信息、案例信息、商业竞争统计信息等等,以及竞争参考,比如商业风险等级、产品分析和规划服务。每个域负责维护自己的业务对象,也负责对其他的域发布服务接口。域为业务对象提供服务检索和维护、封装业务逻辑、定位以及与对象和服务相关联的格式。当主管某个产品或产品领域的人希望从域获得服务时,他们生成一个请求并且两个组确定相互联系,创建服务层次协定。这些联系和协定也存在于域之间。

根据域所有权的概念,一些新的角色和职责应被提供给在 SOA 项目中的开发生命周期,如下面的 表格 1所描述。

表格 1. SOA 项目中的角色和职责

角色 描述
域所有者 管理域的方向,域包含了一个或多个服务的聚集,也包含了业务联系以帮助多个业务单元中的所有者理解业务透视。数据和流程的所有者使用业务分析员来阐明业务目标和需求。跟踪 ROI 计算服务的使用。
域的面向对象业务分析人员 开发人员使用没有假定使用者接口的服务功能性案例。确保完全提取的规格化业务服务都被识别并指定。必须坚持严格且灵活的服务定义和开发生存周期。
业务代表 为域识别和分析业务服务。
域开发人员和维护人员 与面向服务开发生命周期一致的创建和维护服务。创建并实现符合开发规则的服务(例如,服务设计注意事项或 Web 实现指南)、 SOA 以及参考体系结构。
服务测试人员 确保服务经过严格的测试,以获得合适的业务价值。为功能性接口以及它的独立实现创建测试案例。

在给定服务域中工作的人员负责开发业务和技术的集成,以提供可以跨业务界线共享的业务服务,使成员和区域受益。当他们将应用程序中开发的功能转换成服务域中开发的功能时,便会在组织结构(角色和职责)中为应用程序的开发引入变化。







将治理模型投入使用

开发治理模型的流程基于一个具有三个步骤的方法。该方法基于时间约束(time-constrained)客户端项目而开发。成功的关键是治理功能的建立。

  • 步骤 1:实施
    • 在适当的位置设置核心治理功能,并支持客户端业务操作。
    • 边做边学,才能迅速成功。
    • 使用经验丰富的专业人员担当高层管理角色。
  • 步骤 2:专业化
    • 建立必要的结构、流程、方法和工具。
    • 吸取步骤 1 中的经验。
    • 使用有经验的架构师和专业人员。
  • 步骤 3:稳固
    • 传授并培训客户端人员运行操作。
    • 将操作模式变为指导模式。
    • 使用有指导经验的顾问和专家。

图 4 对这些步骤进行了更详细的描述


图 4. 将治理模式投入使用
将治理模式投入使用






提示和技巧

以下是我们从实际项目中获得一些实践经验:

  • 有规律的通知每一个需要访问的人(通过项目通讯稿,或者也许是开会)。SOA 创立了组织文化也改变了技术,这可能会产生沟通障碍,因此互相通信非常重要。
  • 将每个决策、约束和设想记入文档,以确保决策制定的说服力和透明度。
  • 定义关键的交付以及必需的工具集和模板。
  • 为生存周期的管理和方案设置实践工具。
  • 用基本原理定义决策,并文档化和传达这些决策。
  • 必须保持所有风险承担者的有力支持和决策制定者的说服力。






结束语

本文说明了治理为什么重要以及 SOA 项目中需要什么。并对我们 SOA 治理模型的一些关键要素进行了概述。从以 SOA 原则为导向开始,接着描述了体系结构管理流程作为一项关键流程确保了面向服务体系结构的相容性和一致性。还描述了如何为适合的决策制定和开发建立组织结构,以提供所需的角色和职责。最后,本文还讲述了如何将治理模型投入使用,并为您提供了我们在该领域所获得的提示和技巧。

posted @ 2006-04-17 02:48 wsdfsdf 阅读(120) | 评论 (0)编辑 收藏

迁移到面向服务的体系结构,第 2 部分-----简介和概述(继续)

这是一系列文章的第二部分。这一系列文章旨在帮助您更好地理解面向服务的体系结构(SOA)的价值,制订出一个实际的计划来评估您现在的基础架构,并把它转变成一个真正的面向服务的体系结构。其目的在于,当您读完本文时,您将理解为什么声称 SOA 是把现有资产带到未来的最好的平台,同时也使得迅速而正确地开发未来的程序成为可能。另外,您将对在计划这样一次迁移的过程中主要考虑的事项有更好的理解。这一系列文章的第一部分描述了推动考虑 SOA 的动力和这样的一个体系结构的需求。现在,第二部分将继续讨论服务和接口。

服务的性质

什么是服务?如前所述,在一个典型的业务环境里,服务意味着业务函数、业务事务和系统服务。业务函数可能是 getStockQuote、getCustomerAddress 或 checkCreditRating。业务事务可能是 commitInventory、sellCoveredOption 或 scheduleDelivery。系统服务可能是 logMessageIn、getTimeStamp 或 openFile。请注意各种类型服务之间的区别。从应用程序的角度来看,业务函数实际上是原子的非系统函数。业务事务很像是调用应用程序的简单函数,但是它们可能是作为自己的事务的上下文所包含的复合函数来实现的。它们可能包括多个底层函数,这些底层函数对调用者来说是透明的。系统函数是能够从诸如 Windows 或者 Linux 这样的特定平台中抽象出来的广义函数。应用程序框架可能提供像 openFile 这样的广义函数来有效地虚拟化数据源,从而可以在不考虑真实数据源的类型和位置的情况下使用这类函数。

这看起来像人为地规定服务之间的区别;您可以从应用程序的角度断言,所有的服务都是原子的,而与它是业务服务还是系统服务无关。做出这样的区别仅仅是为了引入粒度这个重要的概念。将业务程序分解成服务不仅仅是一个抽象的过程;它具有非常真实的现实含义。根据定义,服务可能是低级(细粒度的)函数,也可能是复杂的高级(粗粒度的)函数,并且在性能、灵活性、可维护性和可重用性方面都有很现实的折衷选择。定义服务的过程通常是在更大的作用域(应用程序框架的作用域)内完成的。这才是必须做的实际工作:也就是开发基于组件的应用程序框架,其中,服务定义为一组可重用的组件,而这些组件又可以用来构建新的应用程序或集成现有的软件资产。

现在,可以获得很多这样的框架;在 IBM,一些像 EWA、JADE 和 Struts (来自 Jakarta)的这样的框架正用在客户集成场景中。以 EWA (读作“Eva”)为例(它来自 IBM Software Group Advanced Technology Solutions 组),在一个较高的层次上,框架看起来如 图 1 所示。在这个框架中,配置定义了一个应用程序,描述了该应用程序的组件以及它们调用的顺序和方法。以源中立的方式接收输入并将其传送到应用程序。因此,举例来说,用现有的 ATM 访问将因特网连接添加到一个银行应用程序,对应用程序逻辑来说是透明的。前端设备和协议处理程序使其成为可能。核心提供系统级服务,而特定用途的使得能够连接后端企业应用程序,这样它们就可以保持原来的状态,或者在一段时间以后进行迁移。虽然 EWA 是完全遵循 J2EE,但是它可以连接到外部基于 DCOM 或 CORBA 组件的系统。


 EWA 框图

现在,EWA 包括超过 1500 个的常规和特定用途的组件,从而大大地减少了编写新的应用程序所需的代码数量。本系列的另一篇文章将详细地研究应用程序框架以及用户在开发这样一个应用程序框架的过程中需要什么。







解决前面的问题

现在,让我们回到讨论第一个集成场景,寻找一个将所需的接口数量减到最少的 Scheme,如 图 2 所示。


将接口减到最少

这张图看起来可能过于简化,但是现在可以很清楚地看出,在像 EWA 这样的框架中,这张图是一个起点。现在,添加属于体系结构概念范围的服务总线(Service Bus)(在 图 3 中用深色的中线表示)和服务或流管理器来连接服务和提供服务请求的路径。流管理器处理定义好的执行序列或服务流,它们将按照适当的顺序调用所需的服务来产生最后的结果。业务流程执行语言(Business Process Execution Language,BPEL)就是这种将流程定义为一组服务调用的技术的例子。


添加总线和执行管理

在这里,您需要确定如何调用服务,因而您将添加应用程序配置。接着,虚拟化输入和输出。最后,提供到后端流程的连接,以便使它们可以按“仅此状态”运行,并且还可以在将来进行迁移。现在,这个高层次的图至少在结构上是完整的了,如 图 4 所示。


完整的基本结构

这张图与 EWA 框图有一些类同之处是毫不奇怪的;在最高的层次上,任何健壮的应用程序框架都必须提供这些功能。然而,从现在起,真正的工作开始了——构建 1500 个组件来丰富这个骨架。这就是为什么很多 IT 架构师选择在一个现有的框架中进行实现的原因;把现有的应用程序分解成用于框架的组件就够了,而不必重新开发所有其他已知将要用到的通用用途组件和系统组件。无论您如何使用它,您都可以使用现有的技术和框架来实现该体系结构,所以您绕了一整圈,现在又回到了开始的地方,在这里,流程首先分析必须解决的业务问题。如果您敢肯定您的体系结构事实上是可实现的,您现在就可以这样做。







体系结构中的集成需求

讨论至此,集成已限定为通过基于组件的服务进行的应用程序的集成,但是集成这个主题比这要宽泛得多。在估计一个体系结构的需求时,必须考虑一些集成的类型或“方式”。您必须考虑如下几方面:

  • 应用程序集成
  • 终端用户界面集成
  • 应用程序连接
  • 流程集成
  • 信息集成
  • 构建集成开发模型。

终端用户界面集成涉及如何集成特定用户访问的全部应用程序和服务来提供可用、高效、一致的界面。它是一个正在发展的主题,而新的发展在近期将主要取决于 Portal 服务器使用方面的进展。虽然 Portlet 已经可以通过 Web 服务调用本地服务组件,但是新技术(比如用户远程 Portlet 的 Web 服务)将使内容和应用程序提供者能够创建交互式服务,这些服务在因特网上可以通过 Portal 即插即用,从而为很多新的集成提供了可能。

应用程序连接是一种集成方式,它涉及体系结构必须支持的所有类型的连接。在一个层次上,这意味着数据的同步和异步通信、路由、转换和高速分布、以及网关和协议转换器等等。而在另一个层次上,它还与输入和输出或源(sources)和汇(sinks)的虚拟化有关,正如您在 EWA 的通道(Channel)和协议转换程序(Protocol Handlers)中所看到的。这里的问题在于数据移入、移出以及在实现体系结构的框架中移动的方式。

流程集成涉及开发映射到业务流程和为业务流程提供解决方案的计算流程、将应用程序集成到流程以及集成一些流程与其他一些流程。虽然第一项需求可能看起来似乎无关紧要,不过就是体系结构提供一个模拟基本业务问题的环境,但是,如果在这一层中不进行充分的分析,体系结构的任何实现注定都将失败,不管它采用的技术是多么的巧妙。将应用程序集成到流程可能包括企业中的应用程序,也可能涉及调用远程系统中的应用程序或服务,而这些远程系统多半属于业务合作伙伴。同样地,流程层集成可能涉及整个流程的集成而不仅仅是来自外部源的单个服务,比如供应链管理或金融服务这样横跨多个机构的流程。为了满足这样的应用程序和流程的集成需求,可以使用像 BPEL4WS 这样的技术,而应用程序框架也可以使用程序配置 Scheme(比如在 EWA 中看到的)。实际上,可以在底层使用 BPEL4WS 来构造一个高层配置 Scheme,然后通过一个引擎来驱动,这个引擎不仅提供流管理,而且还提供其他功能。然而,在构建这一切之前,您应该首先了解体系结构方面的需求,然后,再构建合适的基础架构。

信息集成是一个流程,其作用在于为所有需要它的应用程序提供对企业中全部数据的一致访问,而不管这些应用程序是以什么形式需要它,也不受数据的格式、来源或位置的限制。在实现时,这项需求可能包括 适配器和转换引擎,不过它通常要比这复杂。而关键的概念往往是数据的虚拟化,这可能包括 数据总线(Data Bus)的开发,企业中的所有应用程序都通过标准服务或接口从数据总线中请求数据。因此,不管数据是来自电子数据表、本地文件、SQL 或 DL/I 数据库,还是来自内存中的数据存储,都可以将数据提供给应用程序。永久存储中的数据格式可能还不为应用程序所知。应用程序更不知道管理数据的操作系统,因而访问 AIX 或 Linux 系统中的本地文件的方式与这些文件放在 Windows、OS/2、ZOS 或其他系统中时访问它们的方式相同。同样地,数据的位置也是透明的;由于它是由共同的服务提供的,所以是由访问服务而不是由应用程序来负责查询数据(无论是本地的还是远程的),然后按照请求的格式提供数据。

应用程序开发环境的最后一项需求是,必须考虑可能在企业中实现的集成的所有方式和层次,并且为它们的开发和部署做好准备。要想真正做到健壮,开发环境必须包括(和执行)一种方法来明确地规定如何设计和构建服务和组件,以便促进重用、消除冗余和简化测试、部署和维护。

上面列出的所有集成方式在任何企业中都有一定程度的体现,尽管在某些情况下它们可能是简化的,或者没有明确地进行定义;因而,在着手设计新的体系结构框架时,您必须全面的考虑它们。特定的 IT 环境可能只有很少的数据源类型,因此,消息集成可能会很简单。同样地,应用程序连接的作用域可能也很有限。虽然如此,如果希望框架能够随着企业的成长和变化成功地继续得以保持,则框架中的集成功能仍然必须由服务提供,而不是由特定的应用程序来完成。







部署面向服务的体系结构的好处

面向服务的体系结构可以基于现有的系统投资来发展,而不需要彻底重新创建系统。如果组织将开发力量集中在创建服务、利用现有的技术、结合基于组件的方法来开发软件上,将获得如下几方面好处:

  • 利用现有资产 —— 这是首要的需求。通过使用适当的 SOA 框架并使其可用于整个企业,可以将业务服务构造成现有组件的集合。使用这种新的服务只需要知道它的接口和名称。服务的内部细节以及在组成服务的组件之间传送的数据的复杂性都对外界隐藏了。这种组件的匿名性使组织能够利用现有的投资,从而可以通过合并构建在不同的机器上、运行在不同的操作系统中、用不同的编程语言开发的组件来创建服务。遗留系统可以通过 Web 服务接口来封装和访问。
  • 商品化基础架构 —— 在所有不同的企业应用程序之间,基础架构的开发和部署将变得更加一致。现有的组件、新开发的组件和从厂商购买的组件可以合并在一个定义良好的 SOA 框架内。这样的组件集合将被作为服务部署在现有的基础构架中,从而使得可以更多地将基础架构作为一种商品化元素来加以考虑
  • 更快的产品上市速度 —— 组织的 Web 服务库将成为采用 SOA 框架的组织的核心资产。使用这些 Web 服务库来构建和部署服务将显著地加快产品的上市速度,因为对现有服务和组件的新的创造性重用缩短了设计、开发、测试和部署产品的时间。
  • 减少成本 —— 随着业务需求的发展和新的需求的引入,通过采用 SOA 框架和服务库,为现有的和新的应用程序增强和创建新的服务的成本大大地减少了。同样,开发团队的学习难读也降低了,因为他们可能已经熟悉了现有的组件。
  • 降低风险 —— 重用现有的组件降低了在增强或创建新的业务服务的过程中带来的风险。如前所述,这也减少了维护和管理支持服务的基础架构的风险。
  • 持续改进业务过程 —— SOA 允许清晰地表示流程流,这些流程流通过在特定业务服务中使用的组件的顺序来标识。这给商业用户提供了监视业务操作的理想环境。业务建模反映在业务服务中。流程操纵是以一定的模式重组部件(构成业务服务的组件)来实现的。这将进一步允许更改流程流,而同时监视产生的结果,因此促进了持续改进。
  • 以流程为中心的体系结构—— 现有的体系结构模型和实践往往是以程序为中心的。应用程序是为了程序员的便利而开发的。通常,流程信息在组件之间传播。应用程序很像一个黑匣子,没有粒度可用于外部。重用需要复制代码、合并共享库或继承对象。在以流程为中心的体系结构中,应用程序是为过程开发的。流程可以分解成一系列的步骤,每一个步骤表示一个业务服务。实际上,每个过程服务或组件功能都相当于一个子应用程序。将这些子应用程序链接在一起可以创建能够满足业务需求的流程流。这种粒度允许利用和重用整个组织中的子应用程序。






未来 —— 新模型,新需求

到目前为止,讨论集中在满足现有业务的需求、更好地利用和重用资源以及集成现有的和新的应用程序的相关概念上。但是,一个全新的应用程序模型究竟是什么样的呢?面向服务的体系结构的观念是否仍然有意义或者是必不可少的呢?实际上,两种新的概念已经开始实现了:网格计算(Grid Computing)和按需计算(On-demand Computing)。虽然这两个模型是截然不同的,并且是独立开发的,但是它们之间的关系又是非常的紧密,而每个模型都使 SOA 的发展更加势在必行。

网格计算


深入讨论网格计算超出了本文的范围,但是有几个要点值得提及的。其一,网格计算不仅是使用拥有大量 MIPS 的应用程序来进行计算的解决方案,它还涉及包括硬件、应用程序和数据在内的所有系统资源的虚拟化,因此,在网格中,无论在什么地方,用什么方法,只要需要就可以利用这些资源。其二,前面的章节已经讨论了虚拟化数据源和将应用程序分解成基于组件的服务的重要性,所以很容易理解在网格环境中,一个真正的 SOA 应该更好地获得最多的资源。

按需计算


On-demand 也不在我们讨论的范围之内,但是如果在这里不简要地介绍一下 On-demand 和 SOA 之间的关系,那将是不负责任的。Web 服务是实现 SOA 的技术,而 SOA 是实现 On-demand 应用程序的体系结构。应用程序必需运行在 SOA 框架内,以便获得 on-demand 的好处。

On-demand Web 服务 On-demand 是涵盖宽谱系的 On-demand 消息的一部分。谱系的一端集中于应用程序环境,而另一端则集中于包括像基础架构和自主计算在内的操作环境。业务转换利用应用程序和操作环境来创建 On-demand 业务。On-demand 业务最核心的是 On-demand Web 服务,应用程序层的服务可以按照准时制(just-in-time)集成能力的要求来发现、重构、装配和交付。

Web 服务作为一项切实可行的技术的希望在于,它将通过提供诸如按需服务这样的能力提高业务价值,并且随着时间的推移将转变 IT 组织开发软件的方式。它甚至完全有可能通过 Web 转变在利益共同体(包括贸易合作伙伴、客户和其他类型的合作关系)中经营业务以及提供产品和服务的方式。如果您所有的应用程序共享相同的传输层协议?如果它们都理解相同的接口?如果它们能够参与并理解相同的事务模型?如果您的伙伴也一样?当这一些都实现的时候,展现在您面前的将是什么样的场景呢?相信到那时,您将拥有应用程序和基础架构来支持不断变化的业务情况;您将获得 On-demand 。而 Web 服务和 SOA 会使这一切对应用程序成为可能。







总结

面向服务的体系结构是下一步应用程序开发的重点。服务和面向服务的体系结构都是关于使用异构网络可寻址的软件组件来设计和构建系统的。面向服务的体系结构是一种具有特殊性质的体系结构,它由强调互操作性和位置透明度的组件互连而成。它常常是在现有系统投资的基础上发展起来的,并不需要彻底重新开发全部的系统;它通过利用当前的资源(包括开发人员、软件语言、硬件平台、数据库和应用程序)来利用组织现有的投资,从而在提高生产力的同时降低成本和风险。这种可适应的、灵活的体系结构类型为在开发和维护中缩短产品上市时间以及降低成本和风险提供了基础。Web 服务是一些实现 SOA 的技术,而 SOA 正在成为开发响应性好、可适应的新型应用程序所选择的体系结构。

posted @ 2006-04-17 02:45 wsdfsdf 阅读(177) | 评论 (1)编辑 收藏

迁移到面向服务的体系结构,第 1 部分-----简介和概述

这是一系列文章第一部分,这一系列文章旨在帮助您更好的理解面向服务的体系结构(SOA)的价值,制订出一个实际的计划来评估您现在的基础架构,并把它转变成一个真正的面向服务的体系结构。其目的在于,当您读完本文时,您将理解为什么声称 SOA 是把现有资产带到未来的最好的平台,同时也使得迅速而正确地开发未来的程序成为可能。另外,您将对在计划这样一次迁移的过程中主要考虑的事项有更好的理解。

开发面向服务的体系结构的情况

在过去的40年里,软件体系结构试图处理日益增长的软件复杂性。但是,复杂性仍在继续增加,传统的体系结构好像已经达到了它们处理此类问题的极限。同时,IT 组织的传统需要仍然继续存在;比如,需要对新的业务需求进行快速的反应,需要不断地减少业务中 IT 的成本,以及吸收、集成新的业务伙伴和新的客户群。作为一个产业,我们经历了能够提供完全的分布式处理的多种计算体系结构和能够运行在任何平台上的编程语言,从而大大缩短了实现的时间表,我们还经历了无数的连接性产品,这些产品能够更快更好地集成应用程序。然而,我们还是没有找到完全的解决方案。现在,业界提出面向服务的体系结构(SOA)作为软件体系结构中下一个发展的阶段来帮助 IT 组织满足他们面临的越来越多的复杂性的挑战。可是,这种体系结构现实吗?即使它可以被概括和描述出来,它也能真的被实现吗?本文的论点就是断定 SOA 是现实的;在所有天花乱坠的宣传尘埃落定之后,所有夸大的期望又回到了现实之中,您将发现至少现在 SOA 是 IT 组织可以将其现有的资产带到未来同时又构建新的应用程序系统最好的基础。这是一系列文章的第一部分,它旨在帮助您更好地理解面向服务的体系结构(SOA)的价值,并且制订出一个切实可行的计划来评估您现有的基础架构,然后将其迁移到一个真正的面向服务的体系结构。

曾几何时,现有的 Web 服务技术刺激了关于面向服务的体系结构(SOA)的讨论。这个讨论并不新鲜;从 CORBA 扩展到在完全不同的异类平台上应用程序一直到现在,这个概念已经发展10多年了。集成这样的应用程序的问题不断出现,通常是因为有那么多不同的(非 CORBA 兼容的)对象模型流行起来;因而,很多架构师和工程师都陷入了解决此类问题的泥淖中,开发一种更健壮的体系结构来实现简单、快速和安全的系统和应用程序集成的承诺并没有兑现。然而,问题却在继续增加,并且日益复杂。基本的业务需求,诸如降低成本、减少开发周期、跨企业集成、企业到企业(B2B)和企业到顾客(B2C)集成、更大的投资回报率(ROI)、创建自适应的和自响应的业务模型等等,使我们不停地寻找更好的解决方案;但是,我们越来越觉得“点解决方案(point solutions)”不能解决这样的基本问题。在很多情况下,问题在于缺乏一个一致的体系结构框架,在这种体系结构中,可以快速地开发、集成和重用应用程序。更重要的是,我们需要一个这样的体系结构框架,它能够装配组件和服务,以便快速甚至动态地交付应用程序。为什么像 Web 服务这样的某种技术是好的,但是我们真正需要的是一种不受技术约束的体系结构,有很多文章对此进行了讨论。让我们首先考虑一些基本的问题,这些问题是我们寻求更好的基础的依据,如何解决这些问题将决定我们工作的成败。

首要问题 - 复杂性


一些事情总是相同的,特别是 IT 组织所面对的业务问题。公司管理层总是努力争取更好地利用 IT、获取更大的投资回报率(ROI)、集成历史上分离的系统和更快地实现新系统;但是时至今日,事情发生了些许变化。现在,您遇到的是更复杂的环境。必须重用而不是替换遗留系统,因为考虑到更有限的预算,替换的成本是高昂的。您将发现费用低廉、无处不在的 Internet 访问使得建立一个全新的业务模型成为可能。公司至少需要评估这个模型,因为竞争使然。合并和收购的增长已经成为家常便饭,因此必须将整个 IT 组织、应用程序和基础架构集成和融合在一起。在这样复杂的环境,点解决方案只会使问题进一步恶化,而决不会引导我们走出重林。必须在一个以异构为基础的环境中开发系统,因为它们必须容纳种类繁多的硬件、操作系统、中间件、语言和数据存储。长达数十年的发展和演化积累起来的影响导致了严重的复杂性。面对所有这些对 IT 业务的挑战,很多 CIO 将应用程序集成作为首要任务也就不是令人惊讶的事情了,如 图1所示。


CIO 优先考虑的事情


考虑一个银行有一些分离的“地窖”——在银行内不为其他系统所知的自包含应用程序系统。这些应用程序系统中的第一个可能是优秀的设计,同样,第二个、第三个等等可能都是。但是每一个都是针对银行中不同业务的,是单独投资的孤立项目。因而,例如 获取账户余额的功能在 ATM 系统、分行出纳员交付系统、信用卡计分系统都是重复的,即便它们存取相同数据库中的相同会计数据数据。现在,假设该银行必须为客户开发 Internet 服务、在线银行或在线贷款发放系统以保持竞争力,结果会怎么样。新系统只会给已经存在的冗余编程问题雪上加霜,除非通过某种方式使得现有的代码可以重用。

真正的集成难题 - 接口多样性


同样考虑 n(n-1)集成问题。任何组织都会碰到某些类型的集成问题;或许是因为一次公司的合并、一个新的商业联盟或者仅仅是需要互连现有的系统。如果 n 个应用程序系统必须直接互连,那么将会产生 n(n-1) 个连接或接口。在 图2中,每个箭头表示一个接口。


集成 N 个应用程序

因此,如果另一个应用程序系统 A(第 n+1 个)必须集成进来,将需要产生、文档化、测试和维护 2n 个新的接口。虽然在上图中,5个应用程序组成的集合需要20个直接接口,但是添加第6个应用程序将需要10个新接口!而更糟的是,必须修改每个已有的应用程序中的代码以包括进新的接口,因而将发生大量的测试费用。您可以立即为 n 个应用程序找到产生最小接口数目(n)的最优解决方案,只为每个附加的系统添加一个新的接口,但是,通过直接连接是做不到的。

将来会怎样呢?


在过去的40多年来,软件开发的实践经历了几个不同的编程模型。而进行的每一次转变在某种程度上都是为了处理更高级别的软件复杂性,并且使得可以通过部件、组件或服务来装配应用程序。近来,Java 技术促成了平台中立的编程,而 XML 促成了自描述,因而也促成了平台中立的数据。现在,Web 服务通过允许应用程序以对象模型中立的方式实现互连,从而克服了另一个障碍。使用简单的基于 XML 的消息传递 Scheme,Java 应用程序能够调用基于 DCOM、遵循 CORBA 甚至是 COBOL 的应用程序。在新加坡的一台大型机上的 CICS 或 IMS 事务能够被一台在慕尼黑的 Domino 服务器上运行的 Lotus 脚本驱动的基于 COM 的应用程序调用。最好的情况是,调用程序很有可能根本不知道该事务在哪里运行、它是由哪种语言编写的以及消息的传输路径。只需提出服务请求,然后就会得到答案。

与其任何一个前身相比,Web 服务更有可能成为提供提供有效的、可靠的和可扩展的机器到机器交互的标准,这是几个技术和文化上必须具备的先决条件适时结合的产物。这些先决条件包括:

  • 无处不在的、开放标准的、低成本的网络基础架构和技术。它有助于一个分布式环境的形成,这个环境更有利于采用 Web 服务,而不是 CORBA 和 DCE
  • 在一个以网络为中心的领域内达到的接受程度和技术成熟水平。它要求互操作性以实现关键的业务目标(比如,分布式协作)
  • 一致同意基于 Internet 的开放标准和相关技术是实现低成本互操作性的最好方法。
  • 基于网络的技术(比如 TCP/IP)、工具集(IDE、UML等等)、平台(比如 J2EE 平台)和相关的方法(比如 OO、服务等等)的成熟水平。它们提供了简化松散耦合的、可互操作的、机器到机器的交互(一种比 CORBA 用户体验到的高级得多的状态)所需的基础架构。

面向服务的体系结构允许设计这样的软件系统,它通过发布的可发现的接口为其他的应用程序提供服务,而其中的服务可以通过网络进行调用。当您用 Web 服务技术来实现面向服务的体系结构时,您是在一个更强大、更灵活的编程模型中创建一种新的构建应用程序的方式,从而降低开发成本、持有成本以及实现风险。SOA 既是体系结构模型,又是编程模型,是一种考虑构建软件的方式。

然而,还有更重要的机会刚刚出现。其中第一个就是网格计算,网格计算不仅是使用拥有大量 MIPS 的应用程序来进行计算的解决方案,而且还将提供一个框架,通过此框架可以动态地定位、重定位、平衡和管理大量的服务,这样,无论系统上的负载如何,总可以保证安全地获取所需的应用程序。而这又明显地需要按需计算的概念(on-demand computing),按需计算可能是在任何配置下实现的,从简单的服务器集群到有1024个节点的 SP2 网络。用户需要解决问题和适当的用于解决问题的计算资源——不多也不少——并且为实际使用的资源付费。

这些新功能的有效使用将需要重新构造许多现有的应用程序。现有的单一应用程序能够在这些环境中运行,但没有以最优的方式来使用可用的资源。这个问题和先前讨论过的问题一起可以产生如下结论:必须作出根本的改变——迁移到面向服务的体系结构。







面向服务的体系结构的需求

根据上面讨论的问题,可以很明显地看出,应该开发一种体系结构来满足所有的需求,这些需求包括:

  1. 首要的一点就是利用现有的资产。现有系统很少可以抛弃,它们通常都包含对于企业很有价值的东西。从战略上讲,目标是构造一个新的体系结构来创造所有想要的价值,但是,从战术上讲,必须集成现有系统,以便随着时间的推移,可以在可管理、渐进式项目中分化或取代它们。
  2. 支持所有必需的集成类型或“样式”。这包括:
    • 用户交互——能够提供单一的、交互式的用户体验
    • 应用程序连接性——通信层构成了所有体系结构的基础
    • 流程集成——编排应用程序和服务
    • 信息集成——联合和移动企业数据
    • 依集成需求而构建——构建和部署新的应用程序和服务。
  3. 允许渐进式实现和资产迁移——这将支持开发这种体系结构的一个最关键的方面:获得更大的投资回报率(ROI)的能力。数不清的集成项目由于它们的复杂性、成本和不切实际的实现进度安排而失败。
  4. 包括一个以标准的组件框架为基础构建的开发环境,促进更好地重用模块和系统,允许将遗留资产转移到这个框架中,并且考虑到新技术的及时实现。
  5. 允许实现新的计算模型;特别是,新的基于 Portal 的客户端模型、网格计算和按需计算(on-demand computing)。

面向服务的体系结构——不只是 Web 服务

Web 服务的出现产生了根本的改变,因为很多 Web 服务项目的成功显示这种技术事实上确实存在,借此您可以实现真正的面向服务的体系结构。它使您又往回走了一步,不仅分析您的应用程序的体系结构,而且还要分析您正设法解决的基本业务问题。从业务的角度来看,它不再是一个技术问题,而是要开发一种应用程序体系结构和框架,可以在其中定义业务问题,还可以以一致的可重复的方式来实现解决方案。

不过,首先必须理解 Web 服务并不等同于 面向服务的体系结构。Web 服务是包括 XML,SOAP,WSDL 和 UDDI 在内的技术的集合,它使您能够针对特定的消息传递和应用程序集成问题构建编程解决方案。随着时间的推移,您有理由相信这些技术将逐渐成熟并最终为更好、更有效、更健壮的技术所取代,但是,就目前的情况而言,它们可以发挥作用。至少,它们是 SOAs 能够最终实现这种观念的证明。那么,面向服务的体系结构实际上是由什么组成的呢?

SOA 只不过是一种体系结构。它不是任何诸如 Web 服务这样的特定技术的集合;而是超越它们的,在理想的情况下,是完全独立于它们的。在业务环境中,SOA 的纯粹的体系结构定义可能会是这样的“一种应用程序体系结构,在这种体系结构中,所有功能都定义为独立的服务,这些服务带有定义明确的可调用接口,可以以定义好的顺序调用这些服务来形成业务流程”。请注意这里的表述:

  1. 所有功能都定义为服务。这仅仅包括业务功能、由底层功能组成的业务事务和系统服务功能。这将会产生粒度问题,后面我们将对此进行讨论。
  2. 所有的服务都是独立的。它们就像“黑匣子”一样运行:外部组件既不知道也不关心它们如何执行它们的功能,而仅仅关心它们是否返回期望的结果。
  3. 在其最一般的意义上来说,接口是可调用的;也就是说,在体系结构的层面上,它们究竟是本地的(在本系统内)还是远程的(在直接系统外)、是用什么互连 Scheme 或协议来调用或需要什么样的基础架构组件来连接,都是无关紧要的。服务可能是在相同的应用程序中,也可能是在公司内部网内完全不同的系统上的不对称多处理器的不同地址空间中,还有可能是在用于 B2B 配置的合作伙伴的系统上的应用程序中。

在所有这些表述中,接口是最关键的,同时也是调用应用程序关注的焦点。它定义了必需的参数和结果的类型;因而,它定义了服务的类型,而不是实现服务的技术。系统的责任是实现和管理服务的调用,而不是调用应用程序。这使得可以认识到两个关键的特征:其一,服务是真正独立的;其二,它们是可以管理的。管理包括许多功能,其中有:

  1. 安全性——请求的授权、加密和解密(在需要时)、确认等等
  2. 部署——出于性能、可用性冗余或其他方面的原因,允许服务在网络内重新部署(移动)
  3. 日志——用于审核、测量等等
  4. 动态重新路由——用于故障排除(fail over)或负载平衡
  5. 维护——管理服务的新版本







总结

在第一部分中,您已经简要地分析了一些导致需要考虑 SOA 的问题,这些需求寄希望于新的体系结构。而在第二部分中,我们将研究服务的类型,构造一个基于服务的组件的应用程序框架和一些将来的计算环境,这些环境将使得 SOA 的开发更加势在必行。

posted @ 2006-04-17 02:44 wsdfsdf 阅读(238) | 评论 (1)编辑 收藏

使用 SDO 和 JDBC Data Access Service 启用SOA

本文对随 IBM® Rational® Application Developer V6 一起提供的数据访问服务(Data Access Services,DAS)进行了概述,并对这些访问服务在使用服务数据对象(Service Data Object,SDO)的面向服务的体系结构 (SOA) 中扮演的角色进行了说明。

引言

IBM Rational Application Developer for WebSphere® Software V6 所包含 JDBC Data Access Services 提供了对面向服务的体系结构的持久化层的标准化访问。数据访问服务 (DAS) 与服务数据对象 (SDO) 密切相关,因此要了解 DAS 的概念,首先需要了解一下 SDO。

在本文讲述的高级部分,将给出一个端到端的示例应用程序,该应用程序使用适合开发人员和架构师使用的 JDBC DAS。该示例使用 XML 对象关系映射信息保存对 SDO 对象图的更改。(请参阅参考资料,以获得有关 SDO 的更多信息。)

什么是 SDO?

服务数据对象(Service Data Objects,SDO)是一项新兴标准,用于表示企业应用程序中的数据。SDO 是信息的容器,设计用于提升开放标准和互操作性。SDO 提供了在整个企业应用程序中表示信息的方法,包括表示层、业务逻辑层和此类层之间的通信,如图 1 所示。


图 1. SDO 概述
图 1. SDO 概述

服务数据对象的主要特性包括:

  • SDO 可以包含嵌套对象。此功能称为对象图,是一种非常灵活的表示数据的方式。例如,图 2 中的 SDO 就表示一个有各种产品的多个订单的客户:


    图 2. SDO 数据图
    图 2. SDO 数据图
  • SDO 支持 XPath,可以访问其封装的数据。XML 路径语言 (XPath) 是一项开放标准,是由 World Wide Web Consortium (W3C) 制定的,用于从 XML 文档访问数据。例如,可以使用以下字符串访问特定的产品:CustomerOrder/Product[name='MP3Player'],其中,CustomerOrder 为 Customer 和 Order 之间定义的关系。

  • SDO 可以作为 XML 构件或 Java™ 对象存在。借助对 XML 的这项透明支持,直接使用 <datagraph> 标记作为开头来传递 XML SDO,就可以通过 Web 服务(或任何 XML 传输,如 REST 或 XML-RPC)传递 SDO。而且,仅在 SDO v1 中使用更改摘要时,才有必要使用 <datagraph> 标记。在其他所有情况下,可以使用任何标记。

  • SDO 包含更改摘要。SDO 更改摘要作为所有活动的历史记录使用,通过使用此功能,应用程序可以将旧数据和新数据区分开。例如,加入某个客户决定下新订单。接受订单的企业系统由图 3 中的高级组件组成。请注意,包含新订单的 SDO 将从门户服务器传递到后端服务。如果没有更改摘要,后端服务必须将 SDO 中的所有数据放入数据库。不过,由于可以访问 SDO 更改摘要,因此,只需要将新数据放入数据库即可,从而提高后端服务的效率。此外,门户服务器可以通过使用更改摘要来传递更小的 SDO,该 SDO 中仅包含在前端所做的更改。


    图 3. 更改摘要
    图 3. 更改摘要
  • SDO 是开放标准。SDO 1.0 和 2.0 规范均是由 BEA® 和 IBM 联合发布的(请参阅参考资料)。任何组织都可以免费使用和实现这些标准。

什么是 DAS?

数据访问服务 (Data Access Service) 根据 SDO 1.0 标准保存 SDO。DAS 可以采用任何持久化机制实现。例如,Rational Application Developer V6 包括了一个 JDBC DAS 和一个 EJB 实体 Bean DAS,允许采用标准方式将 SDO 保存到各种后端系统,从而提升企业应用程序内的互操作性和标准。


图 4. DAS 概述
图 4. DAS 概述

DAS 是一项新兴的规范,其标准化进程仍在进行之中。现在称为 DAS 的新一轮工作就是即将推出的数据访问服务 (DAS) 标准。可以将 DAS 称为 DAS 2.0。DAS 将对 SDO 2.0 规范形成补充,正在制定之中(DAS 被认为处于 SDO 2.0 规范之外)。







面向服务的体系结构中的数据访问服务

SDO 数据访问服务非常适合作为 SOA 服务公开。他们提供了一个标准,用于构建可以在 SOA 服务间共享的后端服务。例如,假如有一个必须和两个不同业务进行通信的企业系统。这两个业务服务使用完全不同的技术保存信息。如果传递给这些服务的消息为 SDO,则两个服务都可以使用 DAS,企业应用程序可以将其看作同一个组织而进行处理,如图 5 中所示。


图 5. SOA 中的 SDO 数据访问服务
图 5. SOA 中的 SDO 数据访问服务

DAS 还可以提高 SOA 的可维护性。实现 SOA 的一个常见毛病就是会假设公开服务总是有好处的。当公开了服务时,要更改非常困难——对于那些向客户或公众公开某种功能的服务更是如此。例如,假设某家银行有一项已公开了数年的服务,由于政府法规的原因,现在必须对其进行更改——在网上传输的消息必须经过加密,如图 6 中所示。


图 6. SOA 中的 DAS 和可维护性
图 6. SOA 中的 DAS 和可维护性

如果有数百合作伙伴访问该服务,该银行不会轻易更改服务,因为其合作伙伴将不再能与他们开展业务。该银行的最佳选择可能就是构建另一个 99% 冗余的服务,并尽力说服其合作伙伴转而使用新服务。这将使用大量资源,而所得到的业务价值也有限。

将 SDO 和 DAS 配合使用,可以减缓这类问题,因为 SDO 是动态性非常强的消息。如果该银行使用的是 SDO,则可以直接通知其合作伙伴对添加的信息进行加密,而不会更改已公开的服务——只需要更改传递给该服务的消息。如果某个合作伙伴仍然发送旧 SDO XML 格式的消息,通过检查 SDO 的内容(并可能与不兼容的业务合作伙伴联系),银行的应用程序将能够对此类情况作出判断,然后按照以前的方式处理此类信息。







使用 SDO 数据访问服务的业务案例

在现有持久化技术的基础上将 SDO 和 DAS 结合使用,除了 SOA 的好处之外,其业务价值何在呢?请考虑以下管理方面的特征:

  • SDO 是一项开放标准。由于 SDO 是一项公开的标准,因此不会出现不得不选用某个供应商的情况。截至本文发布时,BEA、IBM、Versant、Versata 和 XCalia 均推出了 SDO 实现。同样,也已计划对 SDO 的数据访问进行标准化。

  • SDO 和 DAS 可以减少业务所必须维护的代码量。数据访问服务提供了一种标准的方法,用于保存封装在 SDO 中的信息,而不受后端系统的影响(不管此后端系统是使用 JDBC 访问的关系数据库、使用视图 Bean 访问的 LDAP 服务器或是具有 DAS 实现的其他后端系统)。实际上,为了使用异构后端系统而编写的自定义代码与数据访问服务采用标准的方式进行了整合。需要维护的代码较少,通常可以尽可能减少潜在的缺陷,从而缩短投入市场的时间和减少风险。

  • 将 SDO 和 DAS 结合使用,不需要受具体的持久化技术限制。DAS 不仅使应用程序无需依赖于数据库或操作系统,而且还使应用程序独立于整个持久化技术。通过使用多个数据访问服务,应用程序可以支持这些中介的基础持久化机制,而不用更改业务逻辑或呈现逻辑。对于 IT 环境复杂的组织,这样可以减少成本、整合资产,并可以减少将来进行高成本技术更改的风险。

  • 使用 SDO 和 DAS 有得有失。这两项均是新兴技术,尚处于早期发布阶段。很多数据访问服务可能不支持其他持久化技术的最先进功能(除非 DAS 专门为支持该技术而构建)。例如,IBM 的 JDBC Data Access Service 就尚不支持 SDO 表群集环境的分布式缓存。另外,若要充分发挥 SDO 和 DAS 的潜力,可能需要对各种新技术有所了解,包括 Web 服务、XPath 及 SDO 规范。对于开发组织,可以需要进行培训。







按部就班,使用 JDBC Data Access Service

本文剩下的部分将给出一个实例应用程序的实现。就功能而言,CloseOrderApplication 将使用 Rational Application Developer V6 包含的 JDBC DAS 关闭客户的订单。该应用程序将从数据库检索一个 SDO 对象图,对其进行更小,然后保存更改。将数据库架构映射到 SDO 对象图的元数据是使用 XML 编写的。

JDBC DAS 编程模型

图 7 所示的关系图演示了使用 JDBC Data Access Service 开发应用程序时应该有用的编程模型。


图 7. JDBC DAS 编程模型
图 7. JDBC DAS 编程模型
关于示例应用程序
此示例不仅是试验性的代码,因为其中实现了 JavaEE 最佳实践和实际错误处理。如果确实需要利用 JDBC Data Access Service 的代码(通常不过寥寥几行而已),清单 1 和清单 6 无疑是最为相关的了。数据库设置、JavaEE 数据源定义、XML 元数据的 JNDI 查询以及异常处理均属于 JavaEE 开发期间要做的工作,而不属于 SDO JDBC DAS。

在此模型中,JDBC DAS 使用 ConnectionWrapper 对 JDBC Connection 加以包装,以连接到数据存储区。使用 MetadataFactory 创建了 Metadata 的实例。然后使用各种构造(如 Tables、Columns 及 Relationships)定义元数据。数据库查询的等效项在元数据中定义为筛选器。不过,在此示例中,元数据、表、列、关系和筛选器均在元数据中定义,且在 XML 映射文档需要时透明地创建。(请参阅参考资料,以了解如何如上所示,在运行时使用元数据 API。)定义了元数据后,就会将其与 ConnectionWrapper 一起使用,以创建 JDBCAccess。中介可以获取和保存 SDO DataObject 图。

我们将通过执行以下任务来实现此实例应用程序:

  1. 创建 JaveEE 项目
  2. 设置数据库
  3. 定义 XML 元数据
  4. 创建方法
  5. 创建 JDBC 连接包装类
  6. 创建 JDBC 中介
  7. 从数据库检索 SDO DataObject 图
  8. 保存 SDO 图
  9. 关闭连接
  10. 检查应用程序异常
  11. 使用 Servlet 测试应用程序

示例应用程序的先决条件

此示例假设为 SDO DAS 使用 JavaEE 环境。不过并不需要应用程序服务器。IBM JDBC DAS 可以用于任何支持 Java SE 1.3 或更高版本的应用程序中。

1. 创建 JavaEE 项目

在 Rational Application Developer 的 J2EE Perspective 中:

  1. 选择 File => New => Enterprise Application Project。将其命名为 CloseOrder,然后选择 Finish

  2. 右键单击 CloseOrder,选择 New => Dynamic Web Project,将其命名为 CloseOrderWeb,然后单击 Finish

2. 设置数据库

图 8 显示了示例应用程序的数据库架构。其中包含一个 customer 条目和一个指向 order 条目的外键:


图 8. 数据库架构
图 8. 数据库架构

请注意,此处假设管理用户名和密码均为 db2admin

  1. 启动 DB2 命令行处理程序。缺省情况下,可以采用以下方式启动此工具:

    • Linux® 或 UNIX®:
      • 作为数据库管理员登录(比如 su db2admin
      • 键入 db2 并按 Enter
    • Windows®:
      • 选择 Start => All Programs => IBM DB2 => Command Line Tools => Command Line Processor
  2. 使用命令行处理程序执行以下代码:


    清单 1. DB2 命令
    																
    																								
    db2 => CREATE DATABASE EXAMPLE
    db2 => CONNECT TO EXAMPLE USER db2admin USING db2admin
    db2 => CREATE TABLE CUSTOMER(CUST_ID INTEGER NOT NULL, NAME VARCHAR(250), ORDER_ID INTEGER)
    db2 => ALTER TABLE CUSTOMER PRIMARY KEY(CUST_ID)
    db2 => CREATE TABLE ORDER(ORDER_ID INTEGER NOT NULL, STATUS VARCHAR(250), TOTAL INTEGER, CUSTOMER_ID INTEGER)
    db2 => ALTER TABLE ORDER PRIMARY KEY(ORDER_ID)
    db2 => INSERT INTO CUSTOMER(NAME, CUST_ID, ORDER_ID) VALUES ('Roland Barcia', 1, 2)
    db2 => INSERT INTO CUSTOMER(NAME, CUST_ID, ORDER_ID) VALUES ('Geoffrey Hambrick', 2, 1)
    db2 => INSERT INTO ORDER(ORDER_ID, STATUS, TOTAL, CUSTOMER_ID) VALUES (1, 'OPEN', 88, 1)
    db2 => INSERT INTO ORDER(ORDER_ID, STATUS, TOTAL, CUSTOMER_ID) VALUES (2, 'OPEN', 188, 5)
    db2 => ALTER TABLE CUSTOMER FOREIGN KEY(ORDER_ID) REFERENCES ORDER(ORDER_ID)
    
    																
    														

  3. CloseOrder 示例应用程序对 JDBC 数据库使用 JNDI 上下文引用,以避免硬编码数据库连接信息。展开 CloseOrderWeb,并双击 Deployment Descriptor: CloseOrderWeb

  4. 选择 Reference 选项卡,选择 Add... => Resourse reference,然后输入或选择字段值,如图 9 中所示。


    图 9. 数据源 JNDI 上下文引用
    图 9. 数据源 JNDI 上下文引用
  5. JNDI name 字段输入 jdbc/db2/Example,如图 10 中所示。


    图 10. 数据库 JNDI 名称
    图 10. 数据库 JNDI 名称

3. 定义 XML 元数据

若要将数据架构映射到 SDO 数据图,则必须定义中介元数据。


图 11. O/R 映射
图 11. O/R 映射

可以在运行时使用 com.ibm.websphere.sdo.mediator.jdbc.metadata.Metadata 定义元数据,图 7 对此作了简单描述(请参阅参考资料,以获得关于在运行时定义元数据的文档)。不过,我们的示例在 XML 中定义元数据。示例应用程序将元数据 XML 文件添加到类路径中,从而简化打开指向该文件的 java.io.InputStream 的过程,如要求创建中介时。

  1. 在 Rational Application Developer 中,右键单击 CloseOrderWeb 项目,然后选择 New => Source Folder

  2. 输入 xml 作为文件夹名称,然后选择 Finish

  3. 右键单击 CloseOrderWeb,然后选择 Java Resources => metadata,再选择 New => other... => Simple => Folder => Next

  4. 将文件夹命名为 DAS 并选择 Finish

  5. 右键单击 DAS 文件夹,然后采用类似的方式创建一个名为 metadata.xml 的新文件。

  6. 插入以下语句作为其内容:


    清单 2. 将元数据添加到 XML
    																
    																								
    <?xml version="1.0" encoding="ASCII" ?>
    <Metadata rootTable="CUSTOMER" xmlns:="http:///com/ibm/websphere/wdo/mediator/rdb/metadata.ecore" >
    	
    	<tables name="CUSTOMER">
    		<columns name="CUST_ID" type="int" />
    		<columns name="NAME" type="string" />
    		<columns name="ORDER_ID" type="int" />
    		<primaryKey columns="CUST_ID" />
    		<foreignKeys columns="ORDER_ID" />
    		<queryInfo filter="( CUST_ID = ? )">
    			<filterArguments name="CUST_ID" type="int" />
    		</queryInfo>
    	</tables>
    
    	<orderBys column="CUSTOMER.NAME" /> 
    	
    	<tables name="ORDER">
    		<columns name="ORDER_ID" type="int" />
    		<columns name="STATUS" type="string" />
    		<columns name="TOTAL" type="int" />
    		<primaryKey columns="ORDER_ID" />
    	</tables>
    	
    	<relationships name="OWNER" oppositeName="ORDER_RELATION" childKey="CUSTOMER" 
    		parentKey="ORDER" exclusive="false" />
    
    </Metadata>
    																
    														

    列和主键的 O/R 映射应当较为直观。请考虑以下对某些其他元数据标记的描述:

    • <tables rootTable="CUSTOMER">
      SDO 数据对象图必须定义访问的根入口点。在此应用程序中 customer 就是根对象。

    • <queryInfo>
      此标记定义筛选器。如果未定义筛选器,元数据将仍然有效;此时中介会将所有的客户(以及所有相关订单)作为 SDO 数据对象图返回。此处定义的筛选器将 SDO 图的返回缩小,使其仅包含与 filterArgument 匹配的客户。当中介从数据库检索此 SDO 图时,将要求传入一个名为 CUST_ID 的 int 类型参数。请注意,该参数并没有设置 name = "CUST_ID",因为其可能与数据库列名称不同。

    • <relationships>
      此标记定义 CUSTOMER.OPEN_ORDER_ID 的外键关系。在此关系中,customer 是子项,而 order 为父项。"Exclusive" 设置为 false,以指示中介检索所有相关订单,甚至包括没有 customer 引用的 order。如果将其设置为 true,则仅检索至少有一个子 customer 引用的 order 项。

    (如果收到验证错误“Element or attribute do not match QName”,可以将其忽略。本文是入门级的文章,将不在 Rational Application Developer 内设置验证。)

  7. 示例应用程序使用 JNDI 上下文引用查询元数据文件的位置。这样,应用程序就可以避免对文件名称进行硬编码了。展开 CloseOrderWeb,然后双击 Deployment Descriptor: CloseOrderWeb

  8. 选择 Reference 选项卡,然后选择 Add... => Resourse reference,并按照图 12 所示填写值。


    图 12. 元数据资源环境引用
    图 12. 元数据资源环境引用
  9. 在 JNDI name 字段中输入 cell/persistent/string/CloseOrderMetadata,如图 13 所示。


    图 13. 元数据 JNDI 名称
    图 13. 元数据 JNDI 名称

4. 创建方法

现在已经准备好,可以开始开发应用程序的代码了。

  1. 右键单击 CloseOrderWeb 项目,并选择 New => Class

  2. 在 package 中输入 developerworks.sdo.example 并将其命名为 CloseOrderApplication

为了更好地描述该应用程序,将在接下来的每一步对 CloseOrderApplication 类的各个方法单独进行讨论。首先是该类的唯一公共方法 closeOrder(),该方法负责整个示例应用程序的组织(图 14)。


图 14. CloseOrder 示例应用程序的事件序列
图 14. CloseOrder 示例应用程序的事件序列

以下方法是应用程序的入口点,图 14 显示的每个步骤几乎都由其进行组织:


清单 3. closeOrder 方法
												
																		
public void closeOrder(int customerId) {
    ConnectionWrapper conn =
        getConnectionWorker("java:comp/env/jdbc/DASDefault "); [1]
    JDBCAccess mediator = 
        createAccessWorker("java:comp/env/DAS/XMLMetadata ", conn); [2]

    DataObject order = null;
    try {
        order = getOpenOrderWorker(customerId, mediator); [3]
    } catch (NoCustomer nc) {
        Logger.warn("CloseOrder app could not find specified customer. [4]
            Prompting end user to create one or cancel transaction.", nc);
        // ... code to notify presentation layer would go here ...
    } catch (OrderNotOpen ono) {
        Logger.warn("CloseOrder app could not find order associated with 
            given customer. Notifying end user.", ono); [5]
        // ... same as above ...
    }

    order.set("STATUS", "CLOSED"); [6]
    persistChangesWorker(order, mediator); [7]
    closeConnectionWorker(conn); [8]
}

												
										

此方法的主要任务是:

  1. 获取 JDBC 连接包装类。
    getConnectionWorker() 代码详细说明数据库如何连接。辅助方法需要 JDBC 的 JNDI 上下文引用。

  2. 创建访问。
    辅助方法需要 ConnectionWrapper 和对 metadata.xml 的 JNDI 上下文引用。

  3. 获取客户的开放订单。
    辅助方法使用中介获取 SDO 对象图,遍历到与根 customer 项相关的 order,然后将其返回。

  4. 处理无客户的异常情况。
    获取开放订单的辅助方法可能引发 NoCustomer 异常。除了记录此情况并通知表示层之外(使用 closeOrder() 进行),典型的异常处理还可能包括使用新连接重试,或尝试采用名称替代 ID 进行查找。

  5. 处理无开放订单的异常情况。
    获取开放订单的辅助方法可能引发 OrderNotOpen 异常。对此的恰当异常处理由读者自行完成。

  6. 关闭订单。
    修改 order SDO DataObject 的状态字符串。

  7. 保存订单。
    将 order SDO DataObject 保存到数据库。

  8. 关闭连接。
    关闭连接。

5. 创建 JDBC 连接包装类

以下代码示例包含创建数据库连接的辅助方法。此方法完成了图 14 所示序列的步骤 (A) 和 (B) 的工作。


清单 4. getConnectionWorker 方法
												
																		
private ConnectionWrapper getConnectionWorker(String ctxRef) {
    Connection conn = null;
    try {
        InitialContext ctx = new InitialContext();
        DataSource ds = (DataSource) ctx.lookup(ctxRef);
        conn = ds.getConnection();
        conn.setAutoCommit(false);
        conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
        return ConnectionWrapperFactoryImpl.soleInstance.createConnectionWrapper(conn);
    } catch (NamingException ne) {
        throw new CloseOrderRuntime("CloseOrder could not lookup jdbc string
            binding: "+ctxRef, ne);
    } catch (SQLException sqle) {
        throw new
            CloseOrderRuntime("CloseOrder failed to make database connection", sqle);
    }
}

												
										

此方法的内容对于具有 JDBC 经验的 JavaEE 开发人员非常简单。唯一特定于 JDBC DAS 代码是从 ConnectionWrapperFactory 创建 ConnectionWrapper。请注意,此处使用了一个泛型运行时异常重新引发假定将由 JavaEE 应用程序中更高层处理的异常。

6. 创建 JDBC 中介

以下代码示例包含创建中介的辅助方法。此方法完成了图 14 所示序列的步骤 (C) 和 (D) 的工作。


清单 5. createAccessWorker 方法
												
																		
private JDBCAccess createAccessWorker(String ctxRef, ConnectionWrapper conn) {
    JDBCAccess mediator = null;
    String xmlPath = null;
    try {
        InitialContext ctx = new InitialContext();
        xmlPath = (String) ctx.lookup(ctxRef); <b>[1]</b>
        InputStream is = getClass().getClassLoader().getResourceAsStream(xmlPath); <b>[2]</b>
        mediator = JDBCAccessFactory.soleInstance.createAccess(is, conn); <b>[3]</b>
    } catch (NamingException ne) { <b>[4]</b>
        throw new CloseOrderRuntime("CloseOrder could not lookup metadata string 
            binding: "+ctxRef, ne);
    } catch (FileNotFoundException fnfe) {
        throw new CloseOrderRuntime("CloseOrder app cannot find: "+xmlPath, fnfe);
    } catch (IOException ioe) {
        throw new CloseOrderRuntime("CloseOrder app has filesystem error", ioe);
    } catch (AccessException me) {
        throw new CloseOrderRuntime("Metadata inside "+xmlPath+" is invalid.", me);
    }   
    return mediator;
}

												
										

此方法的主要任务是:

  1. 使用 JNDI 上下文引用获取文件名。
    采用与查询 JDBC 数据源类似的方法检索 XML 元数据文件名。

  2. 创建文件流
    使用文件名创建指向 XML 元数据文件的常规 java.io.InputStream。

  3. 创建 JDBC 访问。
    使用 JDBCAccessFactory,并将文件流和数据库连接包装类作为参数,以创建中介。

  4. 处理异常。
    此处也是使用一个泛型运行时异常处理各种异常。

7. 从数据库检索 SDO DataObject 图

以下代码片段包含了从数据库检索 SDO 对象图并返回客户的开放订单的辅助方法。此方法完成图 14 所示序列中的步骤 (E) 的工作。


清单 6. getOpenOrderWorker 方法
												
																		
private DataObject getOpenOrderWorker(int customerId, JDBCAccess mediator) throws NoCustomer, OrderNotOpen {
    DataObject graph = null;
    try {
        DataObject param = mediator.getParameterDataObject();
        param.setInt("CUST_ID", customerId); [1]
        graph = mediator.getGraph(param); [2]
    }
    catch(AccessException me) {
        throw new CloseOrderRuntime("CloseOrder app failed to get customer graph from 
            mediator. CUST_ID="+customerId, me);
    }
    
    List cList = graph.getList("CUSTOMER"); [3]
    if(cList.size() == 0) {
        throw new NoCustomer("CloseOrder app could not find customer for 
            CUST_ID="+customerId);
    }
    DataObject customer = graph.getDataObject("CUSTOMER.0"); [4]
    
    if(customer.getInt("ORDER_ID") == 0 || graph.getList("ORDER").size() != 1) {
        throw new OrderNotOpen("CloseOrder app did not find an open [5]
            order for customer with CUST_ID="+customerId);
    }
    
    return customer.getDataObject("ORDER_RELATION"); [6]
}

												
										

此方法的主要任务是:

  1. 创建参数。
    创建一个名为 CUST_ID 的参数,并将其设置为 customerId。此参数在筛选器中使用,以将 SDO 图限制为仅包含具有元数据 XML 中指定的特定 ID 的客户。

  2. 获取 SDO DataObject 图。
    使用步骤 1 中构造的参数对中介调用 getGraph 方法。此图中应包含客户及其相关订单。

  3. 检查客户是否存在。
    getList("CUSTOMER") 方法返回 SDO 图中所有客户数据对象的列表。如果大小为零,则将引发 NoCustomer 应用程序异常。

  4. 获取客户。
    从 SDO 图获取客户。请注意,追加到 CUSTOMER.0 的零是必需的,用以指示要检索 customer 列表的哪个元素(在此例中,列表中仅有一个客户)。

  5. 检查是否存在开放订单。
    如果订单不是开放状态,则不能对其进行关闭操作。将检查 OPEN_ORDER_ID 外键,还将检查 order DataObject 列表是否为非零。

  6. 返回开放订单。
    通过遍历元数据中定义的关系,从 customer 子图检索开放订单。

8. 保存 SDO 图

以下代码示例包含保存已更新 SDO DataObject 图的辅助方法。此方法完成了图 14 所示序列的步骤 (G) 的工作。


清单 7. persistChangeWorker method
												
																		
private void persistChangesWorker(DataObject graph, JDBCAccess mediator) {
    try {
        mediator.applyChanges(graph);
    } catch(AccessException me) {
        throw new CloseOrderRuntime("CloseOrder app failed to persist SDO graph.              
            Access="+mediator+"\nGraph="+graph, me);
    }
}

												
										

9. 关闭连接

以下代码示例包含关闭数据库连接的辅助方法。此代码完成了图 14 所示序列的步骤 (H) 的工作。


清单 8. closeConnectionWorker 方法
												
																		
private static void closeConnectionWorker(ConnectionWrapper conn) {
    try {
        conn.getConnection().close();
    } catch (SQLException sqle) {
        throw new CloseOrderRuntime("CloseOrder app failed to close 
            ConnectionWrapper="+conn, sqle);
    }
}

												
										

10. 检查应用程序异常

CloseOrderApplication 使用了以下异常,这些异常都位于 developerworks.sdo.example.exception 包内:


清单 9. CloseOrderApplication 所使用的异常
												
																		
public class CloseOrderRuntime extends RuntimeException {
    public CloseOrderRuntime() {
        super();
    }
    public CloseOrderRuntime(String msg) {
        super(msg);
    }
    public CloseOrderRuntime(Exception nested) {
        super(nested);
    }
    public CloseOrderRuntime(String msg, Exception nested) {
        super(msg, nested);
    }
}

public class NoCustomer extends Exception {
    public NoCustomer() {
        super();
    } 
    public NoCustomer(String msg) {
        super(msg);
    }
}

public class OrderNotOpen extends Exception {
    public OrderNotOpen() {
        super();
    }
    public OrderNotOpen(String msg) {
        super(msg);
    }
}

												
										

11. 使用 Servlet 测试应用程序

  1. 右键单击 Deployment Descriptor: CloseOrderWeb 项目,然后选择 New => Servlet...

  2. 在 Name 字段输入 TestCloseOrder,然后单击 Next

  3. 在 Java package 中输入 developerworks.sdo.example.test,然后单击 Finish

  4. 插入以下代码作为 doGet 方法的内容:


    清单 10. 测试 Servlet
    																
    																								
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws 
        ServletException, IOException {
    	String customerId = request.getParameter("customerId");
    	CloseOrderApplication coa = new CloseOrderApplication();
    	coa.closeOrder(Integer.parseInt(customerId));
    	response.getWriter().print("Close order request processed successfully.");
    }
    																
    														

  5. 选择 Servers 选项卡,右键单击 WebSphere Application Server v6.0,然后选择 Start

  6. 再次右键单击服务器,并选择 Add and remove projects...,以将 CloseOrder EAR 项目部署到服务器。

  7. 部署了项目之后,使用以下 URL 在 Web 浏览器中打开管理控制台:http://localhost:9060/admin。

  8. 选择 Log in => Security => Global security => JAAS Configuration => J2C Authentication data => New,并按照图 15 所示填写表单。


    图 15. 数据库身份验证入口
    图 15. 数据库身份验证入口
  9. 选择 OK,然后选择 Save

  10. 选择 Environment => WebSphere Variables => DB2UNIVERSAL_JDBC_DRIVER_PATH 并输入您的 DB2 驱动程序目录。Windows 下的缺省值为 C:\Program Files\IBM\SQLLIB\java

  11. 选择 Resources => JDBC Providers => New 并按照图 16 所示填写表单。


    图 16. JDBC Provider 配置
    DB2-Provider.PNG
  12. 依次单击 NextOKSave

  13. 选择 DB2 Universal JDBC Driver Provider (XA) => Data sources => New

  14. 插入 jdbc/db2/Example 作为 JNDI name。

  15. 选择 DB2 Login 作为 Component-managed authentication alias。

  16. 输入 EXAMPLE 作为 Database name。

  17. 输入 localhost(或 DB2 的主机)作为 Server name,然后单击 Save

  18. 为了确保数据源正常工作,请选择 DB2 Universal JDBC Driver XA DataSource 旁边的框,并单击 Test connection

  19. 最后一个管理步骤就是 metadata.xml 文件的 JNDI 字符串绑定。选择 Environment => Naming => Name Space Bindings => New => String => Next 并按照图 17 所示填写表单。Name Space value 中的 Name 为 string/CloseOrderApp/metadata


    图 17. XML 文件名字符串绑定
    图 17. XML 文件名字符串绑定
  20. 选择 Next => FinishSave

  21. 重新启动服务器,以确保所有 JNDI 绑定均已更新。

  22. 若要运行该应用程序,请将以下 URL 输入到 Web 浏览器中:http://localhost:9080/CloseOrderWeb/TestCloseOrder?customerId=2







结束语

JDBC Data Access Service 提供了对面向服务的体系结构的持久化层的标准化访问。本文演示了 SDO DAS 如何如何适应大型的企业部署,以及如何使用简洁且用户友好的 XML 元数据将现有数据库架构映射到 SDO。

posted @ 2006-04-17 02:33 wsdfsdf 阅读(425) | 评论 (0)编辑 收藏

SOA 重用工程

探究将软件重用到面向服务的体系结构 (SOA) 时对其起负面作用的因素,了解重用工程如何给 SOA 价值实现过程带来积极影响。

引言

对于许多组织而言,有效而系统的软件重用仍然是一个很难达到的目标。现在真的存在很多与重用相关的业务促进因素。首当其冲的可能就是 IT 成本削减以及对 IT 体系结构和基础系统中的灵活性和响应能力的迫切需要。

通常,您同样也会发现阻碍进行更为成功的重用起负面作用的因素(或者,至少看起来是这样的)。不过,要应付这些起负面作用的因素却并不容易。同时,面向服务的体系结构 (SOA) 方面的技术演变为实现软件重用提供了基础。SOA 价值方面的关键部分就是通过软件重用得到的益处。







作为重用的关键实现技术的 SOA

一项对 developerWorks 和其他开发人员参考资料中的各种 SOA 最佳实践文章的调查表明,有大量的对 SOA 中的接口的重要性的论述。服务接口是集成设计的关键。通过与标准的使用相结合,接口成为了创建松散耦合(服务客户机与服务提供程序的通信不受编程语言和平台的限制)的基本元素。服务需要独立,以使客户机无需了解服务组件的内部工作;实质上,服务作为“黑盒”进行操作。“白盒”重用(或复制与粘贴)中将对源代码进行修改,以在另一个上下文中使用,这种方法很有用,但通常不如“黑盒”重用的好处多。“由于在整个生命周期中可以从黑盒重用获得较多的好处,因此系统的重用程序可以在不进行更改的情况下进行重用”(摘自 Measuring Software Reuse : Principles, Practices, and Economic Models,请参阅参考资料)。服务对功能进行封装,此功能可以是业务功能或实用功能。在 developerWorks 文章“Migrating to a service-oriented architecture”中对 SOA 属性进行了更为详细的讨论(请参阅参考资料)。

SOA 的所有这些特征提供了可进行软件重用的技术环境。不过,即使有了 SOA 概念和技术提供的重用关键组件,传统的重用阻碍因素仍然是个问题。







重用阻碍因素

在大多数开发组织中,会频繁进行软件重用(至少会临时出现这种情况)。项目之间以一种非正式的方式共享。SOA 提供了更为正式的重用,当服务客户机访问服务以给定功能时,将出现重用。重用方(服务客户机)甚至都不知道其所重用的代码是什么,而且也不需要知道。它们只知道服务正向其提供所需的功能。那么,问题是什么呢?此处,我们将分析一些与可重用服务的创建与使用相关的挑战。

- 教育培训与文化:对某些项目团队而言,Web 服务之类的 SOA 技术可能还是新事物,因而在利用可用服务之前,他们需要学习一些新的技能技巧。项目团队有效找到可用服务,理解其功能并确定给项目带来的好处的能力水平决定了该团队实现服务重用价值的可能性。UDDI 注册中心非常重要,但单单这个还不够。WSDL 文档设计用于供机器读取,人也能读懂其内容,希望重用服务的团队通常需要其他信息。服务学习曲线会对重用价值造成影响,因此,这也是项目团队要考虑的因素,以确定是进行重用,还是重新编写代码。

- 可重用服务的可用性:显然,必须存在有价值的可重有服务才能实现服务重用。确定在给定组中的这些服务,并实际创建和提供它们,可能是一大挑战。必须进行某种层次的域分析,以确定在整个域中存在的共性,从而确定哪种类型的服务具有重用价值。组中的项目团队为其解决方案创建的软件中可能包含可硬编码为可重用服务的良好候选服务,这些服务能够以经济高效的方式在更广泛的范围内使用。了解何种情况下可以进行重用是一个挑战,而提供允许在已确认可以进行重用的地方执行重用的组织构造则更是一大挑战。







重用工程

对工程进行重用的核心是担任跨项目边界的职务的专家(重用工程师)的重用工作。他们在资产的使用和生产方面为项目团队提供帮助。Robert Fichman 和 Chris Kemerer 在“Journal of Systems and Software”发表的一篇文章“Incentive compatibility and systematic software reuse”(请参阅参考资料)中提供了这个描述:

“重用中心的重用工程师实际上是‘外借’给应用程序开发团队以通过重用实践为他们提供帮助。在重用使用方面,重用工程师提供关于潜在的可重用内容的知识,并在任何必要的重用的采用过程中提供帮助。在生产方面,重用工程师识别何处最适合产生新组件,并帮助实现这些组件的可重用性。而对项目而言,重用工程师将记录域的知识、可重用的新资产以及关于哪些现有资产本身已经很好了,哪些尚需要修改或增强的知识。”

重用工程师必须技术熟练,有项目级的经验,且能最终促进重用的实现。重用工程师角色的一个关键特点就是其职位是跨多个项目组的。软件重用是重用工程师的“日常工作”,他们通常在其影响范围内有与重用结构相关的目标和措施。就取得重用程序的成功以及对 SOA 活动而言,对此类涉及的工作领域超过单个项目的角色的投资非常重要。很少有组织通过一次只专注于一个项目而实现了成功的系统重用(Software Reuse: Architecture, Process and Organization for Business Success——请参阅参考资料)。就我对组织应用重用的经验而言,我发现采用这个方法处理传统重用阻碍因素(如前面所述的那些因素)非常有效。对于这些阻碍因素中的每一个,我都将讨论重用工程的影响。

教育培训与文化

具有 SOA 技能的重用工程师通过与项目团队协作,可以降低这些团队采用 SOA 的壁垒。项目经理接受过相关培训,要降低其项目的风险。搜索和重用别人的软件可能有风险,但重用工程师是确定可用服务的专家,可以减少这些风险。他们可以与项目团队合作,以评估和了解需求,然后花时间对服务进行搜索、了解和分析,并为团队提供指导,告知如何以及何时使用这些服务。而且,他们还可以利用其他使用该服务的项目的实现经验。所有这些将降低学习曲线的影响和减少重用风险。这些工程师可以对团队进行培训,告知他们迁移到 SOA 并尽可能少地影响其现有软件的最佳方法。例如,改为使用服务(而不在应用程序内提供此功能)时,可以引入适配器设计模式以尽可能减少对应用程序代码的干扰。

重用工程还对组织文化带来了积极的影响。软件重用并不是一个新概念,多年来各种组织对此进行了很多次尝试,取得了不同程度的成功。因此,重用是大部分人都可以对其有自己的看法的事物,这些看法可能是正面的,可能是反面的,也可以介于两者之间。重用工程师可以了解那些从来不会通过搜索框或表单表达出来的项目需求。人与人之间的交互提供了一个不能通过搜索工具和资产存储库加以解决的通信层次。这在项目团队和重用工程师之间创造出一种和谐的气氛,而这可以进一步帮助创建和引入重用文化,项目团队将在此过程中更加认识到协作重用努力的重要性。重用工程师成为了一个通道,项目团队可以通过他/她获得以服务的形式创建可重用软件资产的机会。

可重用服务的可用性

可以采用多种形式创建服务。对组织而言,第一步是理解哪些是有价值的服务。SOMA(面向服务的建模与体系结构——请参阅参考资料)是一种非常具有描述性的方法,其中包含了几个补充服务识别方法(包括域分解)。重用工程是 SOMA 的补充,因为通过它可以对域加以了解。

域分析可以确定域中存在的共性,从而确定哪种类型的具有重用价值。可以通过若干方法进行域分析。对于重用工程模型,一个项目要进行一次域分析。重用工程师通过与项目团队协作,可以捕获项目团队需要提供的功能。对给定域中此信息的分析,将揭示哪些地方存在对相同功能的重复使用,以及哪些地方可以引入服务以创造重用价值。由于企业体系结构方向和项目团队提供的实际解决方案架构之间的差异,某些广泛的水平重用机会没有被发现(如 developerWorks 文章“Elements of service-oriented analysis and design”中所述,请参阅参考资料),此方法对于发现这种机会特别有效。由于重用的数量可能很大,所以这些常见的服务机会可以迅速体现 SOA 的价值,提供大量的投资回报,这一点非常诱人。

例如,以创建功能需求(如为企业内的应用程序对用户访问进行重新验证)为例。随着越来越关注法律法规的遵守、此类业务控制变得重要得多。由于广泛要求提供此功能,可能组织内一次又一次地重新开发解决方案,最后的结果是没有任何一个解决方案是可以重用的,缺乏业务的集中控制,而 IT 投资被大量浪费。这种类型的功能也可以作为可以广泛重用的一组服务提供,异构企业中的应用程序都可以使用这些服务。各个层次的企业受益人(从 CFO 到应用程序开发人员)都可以实现 SOA 的价值,以一种实际的方式进行重用。

重用工程师在发现这些机会的同时,也会获得可以减少向 SOA 迁移的成本知识。具体来说,重用工程师将对候选服务进行分类。这就是项目团队为其解决方案创建的软件,是一个可能硬编码为可重用服务的候选项,能满足通过域分析确定的需求。了解何处存在这些机会通常是个挑战。重用工程师可以明确地确定最佳的实现,能提供生成服务的最佳机会。重用工程团队也可以担任进行硬编码的角色,从而交付服务。或者,他们可以将以前项目中完成的工作与新项目的要求结合,从而在新项目范围内硬编码为服务。这个“下个项目生成”模型(Measuring Software Reuse : Principles, Practices, and Economic Models——请参阅参考资料)可以提高可重用服务的可用性和使用,能在不需要新投资流情况下实现重用。重用工程是发现那些经常被忽略的机会并针对其进行处理的关键。







总结

重用是有效的 SOA 的必要属性,是 SOA 的业务案例的组成部分。重用工程是将软件重用最佳实践应用到 SOA 的有效方法,可以在整个企业范围内高效地产生和使用服务。

posted @ 2006-04-17 02:26 wsdfsdf 阅读(89) | 评论 (0)编辑 收藏

EJB 倡导者: 使用 Java EE 实现松耦合的 SOA 应用程序

本文探究了面向服务的体系结构中各种形式的松耦合,并重点介绍什么时候是使用消息驱动 Bean 所提供的异步处理能力的最佳时机。

摘自 IBM WebSphere 开发者技术期刊

在每个专栏中,EJB 倡导者都采用独特的前后衔接的对话方式与实际客户和开发人员进行交流,并在期间针对某一大家关注的设计问题推荐解决方案。其中并没有介绍任何确定性的细节,也没有提出“新颖的”或专有的体系结构。要了解更多信息,请参见 EJB 倡导者简介

您对松耦合的定义是否太过狭窄呢?

由于这是 2005 年的最后一篇文章,而且这次交流的是 Java™ Platform、Enterprise Edition (Java EE) 组件而非会话和实体 Bean,所以可以通过这篇文章来很好地总结本专栏所进行的一年之久的讨论,并将所有的组件一起放到完整的面向服务的体系结构中。







问题:太过于关注 SOA 中的会话和实体

亲爱的 EJB 倡导者:

到目前为止您的专栏全部都是关于服务的会话和实体 EJB,它对于直接连接 Java 应用程序是很重要的,例如基于 Web 客户端的 HttpServlets 或富(我们不喜欢说“胖”)客户端的 Swing 应用程序。但我们曾听说面向服务的体系结构都是与松耦合有关的。这不就意味着要尽可能地使用 SOAP 来提供使客户端和服务器应用程序能够独立运行的语言中立性和异步协议?换句话说,为什么您对 JMS 和消息驱动 Bean 讨论得不多呢?

署名:
Feeling Disconnected







对松耦合有许多方面要考虑

亲爱的 Disconnected:

EJB 倡导者关注的是应用程序的服务层,而对客户端介绍得很少,因为我对古谚语形式追随功能 (form follows function) 深信不疑。

其原因在于,许多进行 SOA 的项目之所以失败,是因为它们没有首先建立定义服务的良好模型就开始着手实现细节。

这种倾向相当正常,因为我在 SOA 项目中接触到的大多数人都是架构师和编程人员,他们知道棘手的始终是在细节上,想要尽快解决它们。所以,一旦我们认同好服务的特征是粗粒度、无状态、可通过中介传递和适应的(请参阅 Is it ever best to use EJB components without facades in service oriented architectures?),很明显带有数据传输对象的会话 Bean 就会在实现中扮演重要角色。

但上期专栏介绍了使用实体 Bean 及其 Home 方法代替会话 Bean 的可能性,从而使人们对会话 Bean 是否真的是必需的产生了疑问。图 1 显示了同时使用的两种方法。


图 1. 用有待使用的会话和实体 EJB 实现的服务
图 1. 用有待使用的会话和实体 EJB 实现的服务

图 1 显示了当使用传递过去的会话 Bean 时,纯实体方法(自 EJB 2 开始可用)如何才能有更少的组件和更短的路径长度。其中使用绿色框表示客户端,蓝色框表示各种接口和 Facade 类。橙色框是最常访问的实体 Bean。框和框之间使用双向箭头连接,箭头标有在组件之间通信所使用的协议;蓝色箭头表示相同 JVM 中的 Java 调用,红色箭头表示远程连接(在本例中使用 RMI/IIOP)。为了表示端到端的流向,对流程箭头进行编号,其中 A1-A10 表示从 Java 客户端经过会话 Bean 到实体和返回的流程,B1-B4 表示从客户端直接到实体 Bean 和返回的流程。

客户端用于检索服务接口的编程模型也很简单,虽然在图中没有表示出来。检索会话 Bean 接口需要在 JNDI 上下文中查找会话 Home 并用它创建一个会话;实体 Home 仅仅需要一次查找,其方法可以直接调用而不需要创建对 EJB Object 的引用。以下两段代码示例显示了它们之间的区别。


清单 1. 定位和调用远程会话 EJB 方法
												
																		
Context initCtx = new InitialContext();
Object obj = initCtx.lookup("java:comp/env/ejb/OrderEntry");       
OrderEntryHome home = (OrderEntryHome)PortableObjectRemote(
	obj, OrderEntryHome.class
);       
OrderEntry ref = home.create();

// Method must be invoked on a session reference
CustomerData data = ref.getOpenOrderForCustomer(cID);

												
										


清单 2. 定位和调用等效远程实体 EJB Home 方法
												
																		
Context initCtx = new InitialContext();
Object obj = initCtx.lookup("java:comp/env/Customer");
CustomerHome ref = (CustomerHome)PortableObjectRemote(
	obj, CustomerHome.class
);

// Note how the method is invoked directly   
CustomerData data = ref.getOpenOrder(cID);

												
										

图 1 和相关的代码示例显示了 Java EE 编程模型的真正好处,不管您是否选择使用实体 Home 方法。编程模型逐渐改进并提供向后兼容。简而言之,您的最佳实践能够得以发展而不必强制更改现有的应用程序。另外,JNDI 上下文提供了一个不容忽视的松耦合相关方面:实现独立性

会话或实体 EJB 组件的远程接口提供了位置独立性。使用远程接口使得在相同的 JVM 中部署客户端应用程序和服务组件成为可能,其中它对系统(例如使用 HttpServlets 的 Web 应用程序)的响应时间、吞吐量和可维护性目标有意义。图 2 显示的正是这样的配置,其中企业质量应用服务器(如 IBM® WebSphere® Application Server)在联合部署了客户端和服务组件时“短路”远程接口以使用 Java 并按引用传递(不管服务实现为实体 Home 方法还是会话 Bean)。流程 A1-A6 显示了与服务组件联合部署的 HttpServlet 的使用。流程 B1-B4 显示了它如何被远程富客户端 Java EE 应用程序重用。


图 2. 部署到本地 Web 应用程序和远程富客户端的服务
图 2. 部署到本地 Web 应用程序和远程富客户端的服务

但这听起来像是您已确定松耦合的最重要方面是语言中立性异步操作。并且您认为需要异步操作会使得必须在服务器端使用消息驱动 Bean (MDB) 和 JMS。

在实现 MDB 时,许多编程人员使用的方法是通过其远程接口调用表示服务的 EJB 组件,以使上述位置独立性最大化。然后,不管服务实现是远程还是本地部署,MDB 的目的都是作为简单的适配器,将 MQ 层连接到承载服务的 EJB 容器。JMS 可能由异步客户端应用程序(如果它是 Java)或 MDB 使用(通常用于应答队列)。图 3 显示了服务实现的另一个输入通道的这一配置。


图 3. 用提供异步客户端通道的 MDB 部署的服务
图 3. 用提供异步客户端通道的 MDB 部署的服务

流程 C1-C2 与 D1-D6 分别显示,以阐释客户端和服务器流程的独立性。C2 和 D6 只是对 Writer 是否写入消息进行“确认”,并不意味着等待。清单 3 显示了 MDB 的典型结构,该结构应该有助于阐明它必须做的处理:


清单 3. 典型的消息驱动 Bean 实现
												
																		
public class OrderSubmitMsgHandler implements MessageDrivenBean {
    private transient MessageDrivenContext context = null;

    // Interface supported by either the session Bean or entity Home
    private transient OrderEntry ref;

    public void ejbCreate() {
        // Cache the home according to either snippet one or two
    }
    public void ejbRemove() {}
    public void setMessageDrivenContext(MessageDrivenContext mdc) {    
        context = mdc; 
    }
    // Message acknowledge and database update participate
    public void onMessage(Message inMessage) {
        // Parse the customer from the message
	try {
	    ref.submit(customer); 
	} 
        catch (CustomerDoesNotExist e) {
            // Send JMS message to reply queue from exception
        }
        catch (OrderNotOpen e) {
            // Send JMS message to reply queue from exception
        }
        catch (OrderHasNoItemsException e) {
            // Send JMS message to reply queue from exception
        }
    }
}
												
										

EJB 倡导者现在将回到您提到过的语言中立性问题。看起来您已经将语言中立性的要求与异步处理的要求紧密联系起来了。没有理由不能将这些考虑分开;解析 SOAP 消息和用它调用会话 Bean 的能力应该与该消息的处理是异步(通过 MQ 或者传递 JMS 等效消息的另一个协议)还是同步(例如通过 HTTP,甚至 IIOP)无关。事实上,Java EE 应用程序上的一些早期“发明”的 Web 服务使用 HttpServlet 来解析通过 HTTP 传递的 XML 消息。这种方法最终发展为 SOAP/HTTP。图 4 显示可以在 EJB 组件所实现的服务之上提供的另一个路径。


图 4. 将语言中立性和异步性的考虑分开
图 4. 将语言中立性和异步性的考虑分开

Web Service Servlet 和 Message Driven Bean 可以共享对来自从消息串或 HttpServletRequest 提取的流的数据传输对象进行解析的代码。类似地,响应或应答可以共享从数据传输对象(它可以是 Exception 的一个实例)生成流的代码。

希望这有助于您理解 Java EE 组件的布置,所有这些都将提供某种对面向服务的体系结构很基本的松耦合形式。

对话到此结束,
您的 EJB 倡导者







仍然有太多选项要选择

亲爱的 EJB 倡导者:

谢谢。

我以前不认为像 JNDI 这样的服务和远程接口会提供松耦合。我还可以了解如何将 SOAP 和 MQ 的概念“紧耦合”(按照您提到的方法),以及应该如何尽可能将它们分开。所以将解析和生成 SOAP 消息看作由 Web 服务 Servlet 和 MDB 重用的服务本身是很有意义的。

但谢谢,我不要这样。

在这次讨论之前,SOA 看似非常简单:每个服务都公开一个 SOAP/MQ 接口。现在看起来有好多选择要考虑,并且既然将 SOAP 消息的解析和生成看作服务,那么为什么不想建立一个独立的会话 Bean 来封装它们以便如图中所显示的那样进行重用呢?

再次打扰您,我还是:
Still Disconnected







并非一切都是服务:要使用业务模型加以判定

亲爱的 Disconnected:

这次讨论是当过快要着手实现细节时会出现的情况的一个很好的例子。EJB 倡导者专栏 Which type of EJB component should assemble the data returned by a service? 非常重要,因为它描述了一种定义服务的自顶向下方法,这种方法将服务直接与业务流程模型相关联。这里总结这种方法的基本细节:

  1. 开发一个业务流程模型,显示重要域对象的生命周期中的主要里程碑:

    1. 我们使用状态转换关系图来描述这一模型,其中状态代表里程碑,转换代表促使变成该状态的事件。转换可以看作应用程序所提供的服务(有关示例请参见图 5)。

    2. 我们使用 UML "Actor" 符号来扩展状态转换关系图,以显示当处于该状态时对象的所有者。状态的所有者负责发起转换,从而驱动应用程序的安全模型(也请参见图 5)。

    3. 对于业务流程中的每个状态,我们也对每个需要支持转换动作的域对象的属性和它们之间的关系进行建模。我们通常使用的符号是 UML 类关系图(有关示例,请参见图 6)。为每个状态建立独立的关系图可以让我们随时对变化的对象“形状”进行建模。这些关系图驱动持久性数据。

  2. 开发一个用户界面流程模型,显示在典型“会话”期间来自业务流程的给定参与者如何与系统相交互。

    1. 与业务流程模型一样,我们也使用状态转换关系图,其中状态代表屏幕和对话框,而转换代表实际的 UI 事件,如选择菜单项和按下按钮。根据业务流程转换指定与转换相关的动作。

    2. 还是和业务流程模型一样,我们构建一个类关系图来显示必须在每个状态中可见的数据以支持各种选择。这意味着该数据必须可以从用户输入派生,并以自顶向下的方式驱动服务上的读取操作。

    3. 与业务流程模型不同,我们不需要用 Actor 符号扩展状态关系图,因为关系图本身可以视为单个用户角色的“生命中的一天 (day in the life)”。


图 5. 显示订单生命周期的状态转换关系图示例
图 5. 显示订单生命周期的状态转换关系图示例

图 6. 显示 open 订单“形状”的类关系图示例
图 6. 显示 open 订单“形状”的类关系图示例

这种综合方法可以确保:

  • 将正确的操作分组到一个服务(与业务流程生命周期中的一个状态相关联的所有转换和 read 方法)。

  • 每个服务的用途很好理解(根据相关业务对象来指定动作)。

  • 调用服务需要的前置条件和会产生的后置条件是相通的(当前状态和可选的监护、以及下一状态都是通过转换指定的)。

  • 标识了负责调用服务的用户角色(参与者与每个状态相关联)。

不管是否实现,方法签名都不会提供此信息,但此信息对于好的 SOA 来说是很关键的。否则,编程人员将陷入另一种倾向:一旦有怀疑,就再次构建。因为 SOA 的开发成本比较高(要为图 4 所示的完全松耦合提供各种中介器和适配器),所以这种反对重用的倾向可能会导致获得好处最少。

对您关于简单性的答复中提出的问题的回答是,此信息一点都没有强制您以某种方式公开接口,EJB 倡导者知道简单只存在于旁观者眼中。如果您想要使服务开发人员不必进行选择,只需为每个服务提供图 5 中所示的所有“蓝色”组件即可:

  • 远程服务接口,用于提供同步 Java EE 客户端访问服务操作的位置独立性。

  • 与每个操作相关联的 MDB,通过遵循 JMS 的 MQ 实现来提供异步非 Java 客户端访问。您可以选择编写此 MDB 或不同的 MDB 以期待 JMS 客户端的 Java 消息(从而避免 HTTP 解析开销)。

  • 与每个操作相关联的 Web 服务 Servlet,用于提供同步 SOAP over HTTP 客户端访问。

因为有人会担心这种方法将生成大量未使用的组件,所以另一种简单的方法是,应用 EJB 倡导者喜欢的内容来调用面向客户端的体系结构 (COA);以对客户端最自然的方式给它们提供使用服务正好需要的内容。

这种 COA 方法需要考虑业务流程和 UI 模型的细节,以便为每种方法挑选最可能的候选者。例如:

  • 业务流程生命周期中的状态之间的转换很可能是异步服务的候选者,因为它们将是相关域对象的“所有者”变体。例如,在 open 订单应用程序(我们在上述示例中调用此 OrderEntry)中,submit 方法可以简单地将订单的状态更改为“submitted”,并发送一条 JMS 消息来将其复制到已提交订单应用程序中(我们将这称为一次 OrderFulfillment)。

  • 状态间的转换通常应该是同步的,因为所有者没有改变。举个例子来说明为什么这些操作不应该是异步的,设想一下,如果您进入一位书商的 Web 应用程序,还必须轮询或等待发布-订阅事件来显示目录或将物品添加到购物车中!对于想要通过异步通道使用伪同步方式的读者,请查阅 Bobby Woolf 关于设计消息传递系统的书籍。

  • 只有对于没有相关的非 Java 客户端和服务的集成场景,才提供 SOAP over HTTP 或 MQ。

使用 COA 方法,可以“准时 (just-in-time)”开发组件,这就是 EJB 倡导者喜欢推荐它的原因。

对您的问题(为什么不将所有的东西都看作是服务,甚至是与中介器和适配器相关联的转换)的回答的最后一点是:简单的回答超出了“过犹不及”这一事实。在开发 SOA 或 COA Java EE 应用程序时,最好将服务视为业务流程模型上的操作。服务与应用程序的功能需求有关。中介和相关联的转换与非功能需求有关,例如可靠性、可用性、有效性、可维护性和可移植性。如果您将中介或相关联的转换视作第一个类服务,则最终将使应用程序的真实用途变得模糊。

我知道这其中有很多方面的内容需要理解,所以当您应用这些方法时,遇到相关细节问题不要嫌麻烦,尽管与我联系。

对话到此结束,
您的 EJB 倡导者







结束语

这些交流中谈论了 Java EE 如何为采用面向服务的体系结构的应用程序提供完整的实现框架,其中每个组件或 API 都在一些“松耦合”方面扮演重要角色:

  • 操作系统独立性是由 Java 本身提供的,因为 Java 为组件提供“一次编写,到处运行”的语言,使得您的代码与基础操作系统相分离。

  • 实现独立性是由 Java Naming 和 Directory Interface (JNDI) 提供的,它具备在运行时将逻辑名称绑定到实现的能力。

  • 位置独立性是由远程接口使用 RMI over IIOP 提供给无状态会话 Bean 或封装服务的实体 Home 方法的。RMI/IIOP 是一个相当快的有状态连接,但扩展性不那么好。

  • Web 服务器独立性是由 HttpServlets 提供的,它可以响应同步 HTTP 协议。与 RMI/IIOP 不同的是,HTTP(通常)是一个扩展性很好的无状态协议,但由于消息大小的限制,而且每次都需要在客户端和服务器之间建立和取消连接,所以不能执行得很好。

  • 应用独立性是由异步 Java Messaging Service(或非 Java 客户端的 MQ)和消息驱动 Bean 提供的(用于队列处理程序)。

  • 语言独立性是由标准消息格式(如 SOAP)提供的,不管它是在 RMI/IIOP、HTTP 还是 MQ 上传递。因此,SOAP 可以被每个组件使用,但只有在需要时才使用它,这一点很重要。

相信您可以找到其他方法,我们乐意看到这样的结果。困难的是需要处理与每种方法相关联的权衡。这应该能够让您忙到明年。

posted @ 2006-04-17 02:22 wsdfsdf 阅读(187) | 评论 (0)编辑 收藏

通过服务模拟来简化 SOA 开发

通过用例和模拟对象简化 SOA 开发——特别在您的项目涉及多个团队时——并提高 SOA 应用程序质量。

借助于可重用服务和需要很少的新代码的应用程序(因为可以依赖这些可重用服务),面向服务的体系结构 (SOA) 可以大幅度提高应用程序开发的速度。但是 SOA 还可能大大增加应用程序开发的复杂性,因为团队需要同时进行应用程序的不同部分的工作,而且要在最后成功地将各个部分组合起来。本文将探讨致使 SOA 开发变得困难的原因,并提供了一个可以对其进行简化的流程。各种组织可以使用此流程来极大地增加其 SOA 成功的几率。

SOA 开发问题

使用 SOA 开发应用程序可提供更多的应用程序部署选项,但也使得开发工作变得越发困难。这是因为 SOA 将应用程序开发拆分为两个截然不同的部分:

  • SOA 服务提供程序(SOA Service Provider,SOA-SP) ——该层的代码实现服务。它具有服务 API,以对服务进行声明和为客户机提供调用服务的方法。
  • SOA 服务协调程序(SOA Service Coordinator,SOA-SC)——该层的代码通过一个或多个 SOA-SP 中的服务提供用户功能。它可能具有 UI 或 GUI,以便同传统应用程序一样与 SOA-SC 进行交互。

例如,某个金融应用程序的 SOA 可能如图 1 中所示。


图 1:个人金融应用程序和服务
个人金融应用程序和服务

通常由独立的团队分别负责同时开发这两个独立的部分。一个团队负责开发 SOA-SC——对用户而言的应用程序。另一个团队负责开发 SOA-SP,或许存在多个负责此项任务的团队,而每个团队负责开发若干服务。虽然可能已经实现了一些提供程序,但可能仍然需要专门为此应用程序实现其他的提供程序。

而这给我们提出了第一个问题:如果某些提供程序尚未实现,协调程序开发团队如何开发其负责的应用程序部分呢?

这两个团队——开发服务的团队和开发协调程序的团队——需要使其活动同步。他们必须就服务 API 达成一致;服务 API 可以是简单的 Java™ 接口或 Java Message Service (JMS) 消息格式和队列名称,但必须就此达成一致。但仅就接口达成一致是不够的;服务具有行为,因此团队必须就服务的行为达成一致。服务并不会始终成功地工作,因此团队还必须就错误情况和相应的响应达成一致。

在理想的情况下,多个团队可以非常容易地协调工作,最初的决策可以稍后进行修改,而所造成的影响却非常小,并且评估工作非常灵活,此外还会不断地进行改进。在现实世界中,团队之间经常存在协作问题,往往较早地(甚至不成熟地)做出不可更改的决策,而且评估方法是固定的。

这样就带来了第二个问题:协调程序和提供程序团队如何较早而可靠地就服务如何工作达成一致?

经常通过多个提供程序来实现服务冗余。这样就可以在提供程序之间提供负载平衡和故障转移功能,从而使得协调程序的服务体验更为一致和可靠。冗余可以通过多次部署同一服务实现来实现。不过,当不同的供应商部署了不同的提供程序时,服务几乎肯定具有不同的实现。尽管如此,对于协调程序,所有提供程序的全部实现的工作方式都必须一致,以便协调程序可以采用可交换的方式来调用提供程序。服务的不同实现(特别是来自不同供应商的不同实现)是由不同的团队开发的,而这些团队必须加以协调,以确保开发的是相同的服务。

因此,第三个问题就是:多个提供程序团队如何实现相同的服务,以确保他们的实现具有兼容性?

以上是使用 SOA 进行开发的主要问题。必须实现尚未开发的服务来开发协调程序,协调程序团队和提供程序团队必须就服务如何工作达成一致,而且,多个提供程序团队也必须就服务如何工作达成一致。如果没有良好的流程,这就会导致一片混乱,如果不对其进行检查,将会导致 SOA 项目失败。







SOA 开发流程

下面给出用于对协调程序和提供程序团队进行同步的简单流程,以帮助确保可重用服务以及使用这些服务的应用程序能够成功地进行开发:

  1. 使用服务用例描述服务。
  2. 开发体现服务用例的服务测试。
  3. 开发通过服务测试的服务模拟。
  4. 提供程序团队采用服务模拟作为原型,并将服务测试作为要求,从而实现服务。
  5. 协调程序团队将服务测试作为服务使用者可以进行的工作的示例,并在实际的服务仍然处于开发过程的同时使用服务模拟对其代码进行测试。

这个简单的流程处理了以下问题:如何确定服务的范围以及如何保持团队的一致性和高效率,从而避免发生意外。公正地说,还有许多其他问题仍然没有通过此流程得到解决。该流程并没有涉及服务自身如何开发或协调应用程序如何开发的问题。它并不涉及服务的质量问题(即服务的可靠性问题),而是只定义服务如何提供必要的行为。该流程总体上也不处理传统独立应用程序如何使用 SOA 重新进行体系结构设计,以及如何发现或设计服务。所有这些问题都是必要的,但其并不在此流程的范围之内。

此流程使协调应用程序和服务实现协同工作,并允许团队以相当独立的方式同时对这两个部分进行开发。这并非 SOA 项目所需的全部内容,但却是一个不错的起点。

为了说明此流程,我将讨论如何实现一个简单服务。它就是大家都喜欢用的服务示例,即股票报价服务。为了让内容更丰富一些,我提供了以下三种类型的信息:

  1. 简单的当前价格报价
  2. 包含当前价格、当日最高价和最低价以及当天交易量的复杂报价
  3. 包含过去某天的复杂报价的历史报价

此示例应该足以阐释该流程的工作过程。

服务用例

此 SOA 开发流程中的第一步是开发描述服务的服务用例。

Alistair Cockburn 将用例 定义为“系统涉众之间有关系统的行为的协定”(请参阅参考资料部分列出的 Writing Effective Use Cases)。用例必须适合所定义的系统范围,能够代表此情况下使用系统的主要参与者的观点,且能够在一致的抽象层次上表示参与者的系统使用情况。

Alistair 给出的一个例子是网上的股票购买服务,其中,购买者使用与股票代理的网站协同工作的个人金融应用程序来购买股票。系统范围既包含金融应用程序,又包含代理的网站。购买者是主要的参与者。抽象级别为应用程序和网站之间的交互,而不是应用程序或网站内的详细信息。用例将描述主要成功方案(购买者根据这些方案购买股票)和一些可能出现错误的扩展。

因此,用例是关于以下内容的文本描述:希望系统如何工作、将涉及到哪些人以及他们之间如何交互、系统在正常运行时如何工作,以及出现错误时应该如何处理。它关心的是系统将做什么,而不考虑将如何 实现。

现在,假定所讨论的不是系统或应用程序,而是一个 SOA 服务。用例技术仍然适用。可以采用此技术来描述服务使用者与服务提供程序如何进行交互,说明服务做什么 而不用描述其如何 实现。服务用例 的最初草稿应将重点放在服务的行为上。由于这是必须调用的服务,因此后面的用例草稿还应该指定调用协议——将用于调用服务的技术、传输和数据格式。(用例纯粹主义者甚至可能说协议不属于用例的实现细节,他们是对的。但服务用例不仅描述服务,而且还要描述如何调用该服务,因此协议是使用者和提供程序参与者之间的协定的一部分,必须在某个地方加以指定。)

因此,开发用例的第一步是对服务完成的操作进行充分的描述。此描述代表了使用者对提供程序必须提供的行为的要求,主要由协调程序开发团队创建,但同样以提供程序开发团队提供的输出为基础。这两种类型的开发团队必须对用例满意才行,因为这些用例是对所有团队开发其负责的应用程序部分的要求。

服务不仅要在条件良好的情况下正常工作,而且还要能够恰当地处理出现错误的情况,这非常重要。因此,您的服务用例应该对错误情况和服务无法成功处理的错误输入加以处理。其中很多错误路径最终都表现为用例的备用路径。其他错误场景也可能非常极端,因而需要各自的错误用例。在这两种方法中,用例都必须记录服务如何像成功路径一样全面地处理错误。

示例用例

例如,让我们看看股票报价示例的服务用例。它需要做三件事,因此需要以下三个服务用例:

  1. 简单报价:使用者传入股票代码;提供程序返回指定的股票的当前价格。
  2. 复杂报价:使用者传入股票代码;提供程序返回指定股票的当前价格,当前的最高价格、最低价格以及交易量。
  3. 历史报价:使用者传入股票代码和日期;提供程序返回指定股票和日期的复杂报价。

即便对于这样的简单示例,仍然需要确定很多问题并将其添加到用例中,如下所示:

  • 如果股票代码无效,或者提供程序所属的交易所不支持该股票,该如何处理?
  • 应该为价格使用何种格式?浮点数可能存在舍入误差。小数更为准确,但不标准。字符串效率较低,但更为明确。
  • 应该为复杂报价使用何种格式?逗号分隔值?数组?对象?XML 文档?SOAP 响应?
  • 如果所请求的日期是当日或将来的时间,该如何处理?如果日期是过去的某个市场不开放的日期,该如何处理?对于交易所尚未开始进行股票交易的日期该如何处理?如果日期过早,而不存在相关记录了,该如何处理?如果股票代码或交易从那以后发生了变化,又该如何处理?

即使开发本文中的简单用例也不简单。用例非常麻烦,必须考虑周全才能圆满地完成开发工作。此时的细心工作是非常不错的一项投资;利用好的服务用例可以开发良好的服务测试和服务模拟,从而帮助开发团队正常进行开发工作。






服务测试

此 SOA 开发流程的第二步是开发服务测试,以将用例系统编写为可执行格式。仅当服务恰当地实现了用例时,测试才能通过。

Kent Beck 指出,测试 应该是自动而独立的,而且应该对可能出现问题的部分进行检查(请参阅参考资料部分,以获得有关他的书籍 Extreme Programming ExplainedTest Driven Development 的信息)。测试——通过测试开发工作软件——是 Beck 称为极限编程 (XP) 的方法所包含的十二项实践之一。它是测试驱动的开发 (TDD) 的核心——如果您只能遵循一个实践,该如何执行 XP 呢?当采用 XP 和 TDD 时,将首先开发测试,然后开发软件以通过测试,接着重复这些步骤,直到软件足够完善为止。

应该测试什么?测试的概念源于许多地方,但用例是测试的最佳来源。用例文本和关系图描述用户对需求的理解。测试以更明确的方式表述这种理解,并以可靠和重复执行的代码加以表示。用例和测试是面向不同的受众(人和计算机)以不同形式表示相同内容的对等项。

服务用例的服务测试 没有什么不同,不过更多地将其看作功能测试,而不是单元测试。服务测试不会验证服务如何实现;提供程序开发团队可以自行实现此用途的单元测试。服务测试验证服务是否提供了服务用例认为其应该提供的行为。这些测试还需要对错误路径进行测试。

测试将最终定义服务的期望接口。此接口通常为 Web 服务的 Web 服务描述语言(Web Services Description Language,WSDL)文件、Java 接口或 Java 组件的 EJB 远程接口等等。如果首先开发接口,然后根据接口实现测试,可能会看起来更简单,不过更直接的方法是首先开发测试,然后开发接口,以使测试能够成功编译。

示例服务测试

可以使用简单的单元测试框架(JUnit 或 Cactus)来开发测试。该框架将充当服务的使用者,并进行使用者将进行的操作。下面是一些可能的测试:

  • 使用 IBM 调用 simple quote ,以验证获得的结果是“$100.00”。
  • 使用 MSFT 调用 simple quote,以验证获得的结果是“$30.00”。
  • 使用 BOGUS 调用 simple quote,以验证获得的结果是 invalid stock symbol 错误。

对复杂报价和历史报价的测试将与此类似。另外,还有针对可能的基础结构错误的测试,如远程异常和 HTTP 400 错误。最后,测试应该对服务用例中指定的所有内容进行验证;如果在用例中指定了操作,但却不在一个或多个测试中进行检查,则意味着使用者不能期望提供程序将实际执行该操作。







服务模拟

此 SOA 开发流程的第三步是开发服务模拟——通过服务测试的模拟对象。这些服务模拟是实际服务提供程序的简单原型。

Kent Beck 将模拟对象 描述为测试对象,该对象可以使用常量进行响应,从而实现开销大或复杂的资源的模仿版本。例如,模拟数据库是一个简单对象,但具有数据库的 API,可以接受一些已知的 SQL 字符串,并为每个字符串返回一组固定的结果。模拟对象允许您对组件进行测试,而不必依赖于外部资源。

现在假定此外部资源是一个 SOA 服务。如果您的组件使用该服务,则测试此组件时也在测试该服务。如果服务工作不正常,或者不可用,则即使组件工作正常,测试也会失败。如果服务很慢(通过网络远程调用服务时就是这样),您的测试也会运行得很慢——这样就不能如您所愿频繁地运行测试了。而且,如果服务尚未实现,则根本就不能对您的组件进行测试。

因此,一个不错的方法就是开发服务模拟,模拟对象是实际服务的简单仿真程序。服务具有与实际服务相同的 API;它会实现针对服务测试而开发的接口。服务模拟应该如何工作?它应该通过您已经开发的服务测试,这表明模拟真的和实际服务的工作方式一样。

在某些情况下,服务模拟实际上比实际服务更适合用于进行测试工作。假定您的组件使用返回股票报价的服务。如果传入代码 IBM,您将获得什么样的结果呢?$50?$100?$150?具体取决于当前的股票价格,但这是测试的一个“鸡与蛋”问题。通过使用服务模拟,已硬编码的模拟将始终返回 $100,然后据此进行测试,与测试实际服务相比,这实际上更加可靠。

谁开发服务模拟?提供程序团队(而非协调程序团队)应该开发服务模拟。服务模拟表示提供程序团队计划实际实现的内容的简单实现。如果相同的服务有多个提供程序团队,则他们必须进行协调,以产生一个他们都认可的模拟服务。

示例服务模拟

此示例服务模拟需要通过我前面编写的示例服务测试。因此,它的简单报价实现是一个 case 语句。如果服务只是一个传统 Java 对象(plain old Java object,POJO),则对应的模拟将为通用接口的特殊实现,如下所示:


清单 1:作为通用接口的特殊实现的服务模拟
												
														public class StockQuoteMock implements StockQuoteService

												
										

简单报价则将为 StockQuoteService 中声明的一个方法,并在 StockQuoteMock 实现如下方法:


清单 2:在 StockQuoteService 中声明并在 StockQuoteMock 中实现的简单报价方法
												
														public String getSimpleQuote(String symbol) throws InvalidSymbolException {
	if (symbol == null) throw new InvalidSymbolException(symbol);
	if (symbol.equals("IBM")) return "$100.00";
	if (symbol.equals("MSFT")) return "$30.00";
	if (symbol.equals("BOGUS")) throw new InvalidSymbolException(symbol);
	throw new InvalidSymbolException(symbol);
}

												
										

如果服务更复杂(如无状态会话 Bean 或 SOAP Web 服务),此 POJO 代码仍然可以作为更复杂的模拟实现的基础。在任何情况下,模拟实现肯定都不应该试图处理每个可能的股票代码或访问具有实时数据的数据库。模拟实现应该足以通过服务测试即可。







提供程序开发

此 SOA 开发流程的第四步是由提供程序开发团队实现通过服务测试的服务。

此时,提供程序团队已经准备好,可以进行服务开发了。既然他们还没有开始实现服务,怎么可能进行服务开发呢?幸运的是,他们已经开发了描述服务应如何工作的服务用例,开发人员就是开发人员,他们已经开始考虑如何实现服务了。开发人员已经创建了服务测试,这些测试可说明服务的 API 是什么,并帮助演示服务的行为。他们已经开发了服务模拟,这些模拟是表示实际服务将如何工作的快速原型。

因此,开发人员已经非常明确如何实现服务,只是尚未实现其相关的任何代码而已。

这几乎是毫无疑问的,但开发人员实现的服务必须通过服务测试。他们如何知道自己已经完成服务实现工作了呢?当服务通过了所有测试后,服务就已完全实现了。在开发期间,团队的开发活动可能会让他们添加要测试的其他功能。训练有素的团队不会放弃这些想法,而将对其进行捕获并添加到服务的测试集中。服务实现也必须通过这些测试。提供程序团队还应该向其他提供程序团队和协调程序团队通报这些添加的测试,以便所有团队的测试集保持同步。

理想的情况下,提供程序团队将可以成功地实现通过测试的服务,而不必修改已达成一致的测试。不过,这经常被证明是不切实际的。当开发人员实现服务时,他们有时会发现需要更改服务的接口或行为。如果服务测试的质量良好,而开发人员更改了服务的工作方式,则测试就不能再通过了。为了使测试仍然有效,开发人员必须修改测试,使其可以验证新的设计。更改测试意味着服务模拟现在将不能通过测试,因此也必须对其进行更改,以实际模拟服务现在的工作方式。

如果提供程序开发人员更改了服务测试或服务模拟,他们需要尽快通知协调程序开发人员和该服务的任何其他提供程序的开发人员。任何使用旧测试和模拟的人员都在根据一个现在已经过时的协议进行开发,因此各个团队需要根据新测试和模拟进行同步。如果其他团队拒绝接受新测试和模拟,则重新同步的工作就变成了团队之间的重新协商点。他们仍然有希望就服务用例达成一致,以从此处继续开展工作,从而开发一组一致认可的测试和模拟。

示例提供程序实现

提供程序开发团队将开发实现 StockQuoteService 的类或组件,其工作方式与 StockQuoteMock 类似,并使股票报价测试能够通过。模拟是一个包含硬编码响应的简单对象,而此提供程序是提供实际行为的组件。该实现应该执行以下操作:

  • 支持所有有效股票代码(至少支持提供程序的股票交易中涉及到的所有股票)。
  • 确保使用包含所支持股票的实时价格的数据库。
  • 将数据库使用的价格格式转换为服务返回的格式。
  • 将数据库针对无效代码的输入结果(如空查询结果)转换为服务希望的错误。
  • 实现服务的协议,如 EJB 远程接口、HTTP Web 服务或 JMS 请求和答复消息。

由于模拟和实际提供程序实现相同的接口——在此例中为 Java 接口 StockQuoteService,因此服务测试可以使用两个实现中的任何一个;只要使用要实例化的正确类对测试进行配置即可。为了运行测试,您还需要使用测试期望的股票价格对数据库进行配置。







协调程序开发

此 SOA 开发流程的第五步是由协调程序开发团队实现使用服务的应用程序。在实际服务实现就绪之前,应用程序都将使用服务模拟。

此时,由于具有大量的服务模拟,因此协调程序团队可以继续进行其相关工作,就像已经实现并提供了服务提供程序一样。而且,协调程序团队不仅具有一组可以使用的服务(也就是模拟),而且也有了可以演示服务如何工作的和客户机如何使用服务的一组测试。该团队可以将这些测试作为可以如何实现其协调程序的简单原型使用。和提供程序团队一样,尽管尚未实现任何代码,但协调程序开发团队已经早就在进行协调程序的工作了。

理想情况下,协调程序团队将可以使用达成一致的服务模拟来成功地实现他们的协调程序。不过有时候这样做有些困难。模拟并不提供某些需要的行为或希望的接口。协调程序客户还需要比模拟提供的服务更细粒度的服务。如果服务协调程序需要其他功能,则可以尝试自行实现此功能。如果协调程序需要不同的接口,则可以尝试实现一个适配器,来将其所希望的接口转换为模拟实现的接口。如果协调程序希望更细粒度的功能,则该团队需要对模拟及其测试进行修改。

这些更改会使得有必要重新与提供程序团队进行同步。让我们假定协调程序团队实现了额外的功能或不同的接口来提高服务的可用性。如果添加的行为不是特定于协调程序,而是会涉及到服务,则添加的行为可以潜在地由其他服务使用者重用。因此应将其内置到提供程序中。提供程序所需的更改可以也应该建模为对模拟及其测试的更改。当协调程序团队必须修改模拟及其测试时——既可能是为了增强其他功能也可能是为了对功能进行进一步细化——必须将这些更改应用到提供程序和其他所有的工作内容。已更改的模拟和测试成为协调程序团队、提供程序团队以及其他协调程序提供团队之间的重新协商点。他们必须针对达成一致的一组新模拟和测试重新进行同步。

示例协调程序实现

协调程序开发团队将实现一个委托给 StockQuoteService 的实现的客户端组件。它的行为将与服务测试相似,不同的是,它将使用服务类为 GUI 或客户端应用程序提供真正的功能。协调程序实现只能使用 StockQuoteService 中经服务测试证明可用的功能。Java 编译器将确保协调程序代码只能调用服务接口声明的方法;保持协调程序实现与测试实现的一致可以确保服务按预期的要求工作。






将流程组合起来

那么,该流程在实践中是如何工作的呢?

第一步,开发服务用例。服务用例团队可以包括来自提供程序团队和协调程序团队的代表。或者,这个团队可以仅由那些专门进行需求收集和用例开发的分析人员组成。传统用例开发主要关注人们如何使用应用程序,而这个团队必须将重点放在组件如何集成上。他们不应关心提供程序将如何实现,也不用考虑协调程序可以如何实现。相反,他们应将重点放在服务是什么、它们完成什么工作以及如何对其进行调用上。

第二步,将服务用例编写为服务测试。用例是人可读的,而服务测试表示相同的需求,但采用的却是计算机可执行的方式。这些测试必须由开发人员实现,而不是由开发用例的分析人员实现。测试开发人员可以是提供程序团队和协调程序团队的成员,也可以是可用且有能力实现测试的人员。在最终确定测试之前,每个团队的代表都必须对其进行认可,从而表示所有团队已就其达成了一致,而不考虑谁开发了哪个测试。

第三步,开发通过测试的服务模拟。开发测试的团体通常也实现模拟。模拟证明测试可以通过,作为原型供提供程序团队使用,并支持协调程序团队继续进行开发。与测试一样,除非所有团队都认可模拟并表示同意,否则就不能认为已最终确定了模拟。换句话说,任何团队都不能强制别的团队接受一组测试和模拟,大家必须一致认可,否则迟早会出现混乱。

第四步,提供程序团队部署提供程序,这些提供程序的行为与模拟相似,且均已通过了测试。如果将这些提供程序添加到测试和模拟,尤其是在更改了测试和模拟的情况下,则他们必须分发这些更改,以便其他团队重新进行同步。他们不能强制让其他团队接受这些修改;所有团队必须就此达成一致。

第五步,协调程序团队必须使用模拟开发可以正常工作的协调程序。如果需要更改模拟,他们还需要对测试进行更新。他们需要随后将其更改分发给其他组,所有的团队必须找到一个大家都认可的点——一组共同的测试和模拟,并据此重新进行同步。

这些步骤一起的确可以形成一个简单的开发流程。







解决 SOA 问题

那么,这个流程是否解决了我在本文开始时提出的问题?

1. 如果某些提供程序尚未开发,则协调程序团队如何开发其负责的应用程序部分?

模拟解决了此问题。模拟可以快速地进行开发。虽然实际提供程序的开发需要更长的时间,但协调程序团队可以使用模拟同步开发协调程序。只要满足了以下条件,此工作就可以顺利地进行:

  1. 模拟的功能全面,即意味着其编写的测试和用例也全面。
  2. 没有团队必须更改模拟。只要某个团队必须对模拟进行更改,他们就应该在进一步脱离同步之前尽可能快地重新进行同步。

2. 协调程序团队和提供程序团队如何较早而可靠地就服务如何工作达成一致?

因为测试和模拟可以快速进行开发,而且它们是真正可以运行的实际代码,所以提供了早期验证,从而可以确保用例有意义,并且团队真的达成了一致。有了经验后,可以在前期投入更多的精力,以确保测试和模拟的全面性,这些构件需要更改的几率越小,剩下的开发过程中需要重新进行同步的几率也就越小。

3. 实现相同服务的多个提供程序团队如何能确保他们的实现是兼容的?

一组公共测试以及通过这些测试的模拟可以作为公共参考框架使用,以确保独立的提供程序实现始终兼容且可互换。早期的测试越前面,需要更改的几率就越小,从而团队需要重新同步的情况也就越少。

这样一来,该流程就解决了多个团队实现 SOA 的不同部分时所面临的主要问题。







结束语

本文讨论了以下内容:

  • 在尝试使用 SOA 开发应用程序时,并行的独立团队可能遇到的常见开发问题。
  • 一个简单的五步开发流程,该流程通过使用服务用例、服务测试和服务模拟解决了这些问题。

您可以将此流程应用到您的组织中,从而大幅度提高使用 SOA 进行开发的成功几率。

posted @ 2006-04-17 02:18 wsdfsdf 阅读(149) | 评论 (0)编辑 收藏

FastSOA:用 XML、XQuery 和本机 XML 数据库技术加速 SOA-----中间层 SOA 缓冲体系结构的作用

很多 SOA 实现都依赖于用 XML 定义的消息格式。结果,消息模式可能变得非常复杂、不兼容、难以维护,甚至造成严重的可伸缩性和性能问题。在本文中,Frank Cohen 将介绍如何通过在 SOA 中间层使用 XML、XQuery 和本机 XML 数据库技术来提高 SOA 性能的战略和技术。

很多软件架构师在面向服务体系结构(SOA)设计中使用 XML,虽然没有一种 SOA 标准要求在 SOA 中使用 XML 或者提供相关指南。因此,软件开发社区做了很多实验和调查来发现定义服务端点和消息定义(模式)的最佳方式。这些方法大多数都会带来了糟糕的性能和可伸缩性。

比如,最早提出用 SOA 实现 ebXML 的 General Motors Corp.,其最初的设计使用的是 Universal Business Language (UBL),建立的 XML 消息有 150,000 字节到 10 兆字节甚至更大。2004 年,我的性能测试公司 PushToTest 认为当时的 Java™ 应用程序服务器没有提供足够的吞吐量,在 GM Web Services Performance Benchmark 研究中提出了可伸缩性和性能问题。

当时基于 XML 的 Web 服务技术还非常新,我认为新一代应用程序服务器技术会解决性能问题。但大部分问题仍然存在。

Web 服务吞吐量问题和复杂的 XML

2005 年,PushToTest 完成了一项新的 SOA 性能研究(请参阅参考资料)表明,在处理复杂的 XML 消息时,使用当前 Java 应用程序服务器构建的应用程序其性能很差,不足以投入生产。是发现的问题和以前研究中的问题相同:

  • 简单对象访问协议(SOAP)绑定(代理)低效而缓慢。
  • 每次请求都需要一组全新的资源(对象、CPU 和网络带宽)来处理响应。没有缓冲模式。
  • 使用关系数据库技术存储 XML 数据非常慢而且没有可伸缩性。
为了了解这三个问题,设想一下软件开发人员如何使用 J2EE 应用程序服务器工具构建和部署 XML 服务。


图 1. WSDL 定义的例子
图 1. WSDL 定义的例子

虽然可以使用使用不同技术建立基于 XML 的 Web 服务,但我发现多数开发人员更愿意从服务的 Web Services Description Language (WSDL) 定义开始。Java 应用程序服务器提供了输入 WSDL定义和生成代理类的工具。代理器接收 SOAP 请求并把请求转发给 Java 对象或 Enterprise Java Bean (EJB) 进行处理。SOAP 绑定(代理器)是一种 Java 类,可通过 servlet 接口调用它。


图 2. Java 方法调用
图 2. Java 方法调用

图 2 说明了 Web 服务消费者如何向服务发出 SOAP 请求。SOAP 绑定对 SOAP 消息体中的 XML 内容进行反序列化。这个过程需要进行大量的处理,非常复杂,因为消息体常常包含复杂的数据类型。比如,消费者可能向服务发送包含多个值的散列表。SOAP 绑定需要解码散列表的内容,对每个值创建 Java 对象的实例。散列表还可能包含其他散列表,因此解码 SOAP 消息内容不是一件容易的事。如果不相信的话,请看一看 Apache Axis 反序列化器的源代码。

SOAP 绑定实例化包含 SOAP 消息体内容的 Java Request 对象。SOAP 绑定调用目标类中的目标方法,并将 Request 对象作为参数传递。目标 EJB 或 Java 对象提供所有必要的处理来建立对请求的响应。SOAP 绑定将 EJB 或 Java 对象返回的值序列化到 SOAP 响应消息中。SOAP 绑定将响应对象中的值解码成能够序列化到 SOAP 响应消息中的值需要经过同样复杂的过程。

通过研究用流行的 Java 应用程序服务器工具创建的 SOAP 绑定,我发现了以下问题:

  • 应用程序服务器工具创建的 SOAP 绑定效率很低。比如,我发现某些 SOAP 绑定创建 SOAP 请求的多个副本,每个请求都实例化为 String 对象 —— 这样做并没有明显的理由。一些 SOAP 绑定创建了 15,000 个 Java 对象来反序列化消息体中包含 500 个元素的 SOAP 请求。
  • 在配备有双 CPU 3.0 GHz Intel Xeon 处理器的服务器上,我发现在处理有效负荷 10,000 字节、包含 50 个元素的简单 SOAP 消息时,每秒处理的事务为 15 到 20 个(TPS)。随着 SOAP 消息复杂性和大小的增加,我发现会造成明显的伸缩性和性能问题。有效负荷 100,000 字节、包含 750 个元素的 SOAP 消息会把吞吐量降低到 1.5 TPS。SOAP 消息体中元素个数越多,每个元素嵌套越深,问题就会越严重。

性能问题在 SOA 设计中会引起连锁反应。SOA 是一种组件软件重用技术。一个服务通常调用其他服务来确定对消费者请求的响应,从而形成一个调用链。


图 3. 消费者
图 3. 消费者

不仅仅是一个服务的性能问题,每个服务在序列化、反序列化请求和响应的时候都会增加同样的开销。随着服务调用层次的增加,性能问题也成倍增加。

加快 SOA 失去的机会

除了 SOAP 绑定代理速度慢的问题,SOA 设计还常常忽略或者忽视另外两个问题。

首先,SOA 设计常常忽视了用中间层服务缓冲来提高 SOA 性能的可能性。比如多数 SOA 设计中的 XML 模式都定义了了响应的 time-to-live 值。在这种情况下,缓冲服务响应并在服务再次收到同样的请求时重新使用缓冲的响应是一种提高 SOA 服务性能的合理而适当的方法。

其次,在 SOA 性能测试中,我尝试了各种不同的 XML 消息解析方法,其中包括 Streaming API for XML (StAX)、XML 绑定编译器、Java Architecture for XML Binding (JAXB) 和 Document Object Model (DOM) 技术。一些技术的性能要优于另一些。比如,很多 StAX 解析器能够提供比 DOM 解析器快 2 到 10 倍的性能。

我怀疑如果使用其他东西而不是 Java 对象来提供 SOAP 绑定是否能够改进性能。比如,如果收到的 SOAP 请求在本机 XML 环境中处理,那么基于 Java 的 SOAP 绑定就不再是必需的了,同时还可以避免因为序列化成 Java 对象而导致的性能降低。

此外,一些本机 XML 环境使用 Java Virtual Machine 环境,但会避免构造 Java 对象。比如,Raining Data 的 TigerLogic XDMS 和 Kawa/Qexo 通过将 XQuery 查询直接转换成 Java 字节码来实现 XML 处理代码。这样做是因为与使用 Java 对象相比,使用 XQuery 字节码实现的 XML 处理代码的吞吐量更大,代码更短。

FastSOA 解决方案

FastSOA 是解决这些问题的一种体系结构和软件编码实践:

  • FastSOA 通过减少 Java 对象的需要,更多使用本机 XML 环境提供 SOAP 绑定来解决 SOAP 绑定(代理)性能问题。
  • FastSOA 引入了中间层服务缓冲来加快 SOA 服务。
  • FastSOA 使用本机 XML 持久性来避免 XML 到关系数据库的转换造成的性能问题。

下图显示了 FastSOA 体系结构。


图 4. FastSOA 体系结构
图 4. FastSOA 体系结构

FastSOA 体系结构与现有的基于 Web 的基础结构结合在一起,作为中间层缓冲部署来接收服务消费者的请求。比如,一个消费者向服务发出 SOAP 请求。中间层缓冲提供 SOAP 绑定(代理)。绑定调用 XQuery 在 XQuery 引擎处理 XML 请求文档。XQuery 检查缓冲,查看以前是否收到该请求;在这种情况下,FastSOA 服务可以从缓冲中返回响应,不需要逆流而上再请求服务。该过程通过缓冲加快 SOA 执行从而实现了 SOA 提速。

FastSOA 方法的优点包括:

  • 服务端点是标准的。对于应用程序的其他部分而言,FastSOA 中间层缓冲就像是一种服务。
  • 不需要修改现有的系统或代码。FastSOA 中间层缓冲作为一种数据聚合和迁移服务嵌入到已有的数据中心。
  • 如果上游服务暂时不能用,当服务离线的时候,FastSOA 方法提供了一种浏览缓冲数据的机制。
  • 通过缓冲服务的请求降低了为支持消费者和服务之间的通信通常所需的带宽要求。

为了从实践的角度理解 FastSOA,考虑下面的应用程序。

XML 的例子

General Motors 采用 SOA 模式创建服务,让汽车代理商使用基于 ebXML 的模式和协议从生产厂家订购零部件。该服务能够识别 Software Technology in Automotive Retailing (STAR) 组织的一种 XML 模式。STAR 是大型汽车厂商共同努力的结果,其中包括 GM。STAR 创建并维护 Business Object Document (BOD) 模式,定义了目录检查请求(以及其他许多东西)。

CheckInventory 请求检查请求者和目录的级别与状态。服务消费者根据 STAR 模式创建目录请求文档。消费者将文档编组成请求,并通过网络发送给服务。服务发回目录状态响应说明库存中有哪些零部件。

通过降低网络带宽的需要和减少为了响应冗余请求而造成的服务带宽需要,零件订购服务可以从 FastSOA 模式中受益。

比方说,汽车零售商的零件目录响应中包含一个 Time-To-Live (TTL) 元素。TTL 元素定义了响应有效的秒数。比如 GM 可能将其设为 60 秒。在这 60 秒内,FastSOA 用中间层存储的目录响应缓存响应目录请求。这样服务就减少了带宽的使用,并缩短了请求响应时间。

下表说明了如何计算网络中的服务提速效果,这些服务位于本地网络之外的服务器上,FastSOA 数据缓冲收集服务在本地网络中。


表 1. 计算服务加速效果
动作无缓冲²启用缓冲²
第一次请求处理的时间1765¹2218¹
在缓冲中存储请求的时间453¹
后续相同或冗余请求1765¹320¹
使用的 Internet 带宽30,400 K 字节304 K 位
使用的总时间2941 分钟533 分钟

¹这里所有的时间都是毫秒,1 秒 = 1,000 毫秒。

²假设:

  • 消费者和缓冲服务使用 100 M 以太网连接和 1.5 M 左右的 DSL 连接。
  • Time to Live (TTL) 为 60 秒。
  • 请求/响应包含 38,000 个字节。
  • TTL 期间有 100,000 次请求。
 

  

在 FastSOA 实现中,用 XQuery 实现零部件订购服务。XQuery 请求目录服务,读取响应的内容,在运行时确定是否可以使用以前存储的响应而不必再次请求目录服务。

这样就在服务环境中实现了 FastSOA 数据缓冲收集体系结构。XQuery 和本机 XML 数据库提供了重用以前缓冲响应数据的服务,只要请求与以前的请求匹配并且数据仍然不过时。结果是服务提速了。

FastSOA 技术选择

可以使用 Java 代码和关系数据库技术实现 FastSOA 体系结构。但是,在测试使用 Java 对象创建的服务绑定和使用关系数据库持久 XML 时,我发现了重要的性能和可伸缩性问题。这些问题很突出,考虑使用 XQuery、XSLT 和本机 XML 数据库技术很有必要。

我对 XQuery 感兴趣,是因为它是作为应用程序开发的本机 XML 环境来实现的。与早期的 Java 技术非常相似,XQuery 社区充满了扩张和证明 XQuery 是一种开发平台的活力。实际上,多数 XQuery 实现都经过扩展超出了 XQuery 标准,以便 XQuery 能够进行 SOAP 请求。比如,XQuery 可以查询其他服务、J2EE 对象和通过 JDBC、SOAP、JMS 协议查询数据源。此外,已经有 10 种或更多非常可靠的商业化和开放源码 XQuery 实现。

最后,FastSOA 使用本机 XML 数据库作为中间层缓冲,因为 SOA 数据通常采用 XML 编码格式,而关系数据库在持久存储和索引 XML 这样的层次性非结构化数据方面有很大不足。存储 XML 数据的关系数据库通常使用大型二进制对象(BLOB)字段类型存储 XML。不仅效率低,而且很难建立索引以便快速搜索。对于流数据采用关系方法通常也不是最佳办法。如果在基于 Web 服务的网络中发送 XML 消息,最好用基于流的方法处理该消息,而关系数据库对此无能为力。

FastSOA 的未来

除了本文所述的 SOAP 绑定性能改进之外,采用中间层服务缓冲还会为企业带来很多好处。其他好处包括中间层模式转换、服务版本化、策略选路和服务质量(QOS)处理。比如,FastSOA 提供了中间层 XML 消息模式转换,以便保证需要不同和不兼容的消息类型的服务之间的兼容性。

结束语

本文考察了如何提升 SOA 的性能和可伸缩性,详细介绍了在中间层使用 XQuery 支持结合 XML 持久的 SOA 设计所带来的好处。FastSOA 设计结合使用了本机 XML 持久性和 XQuery,因此每次收到服务调用时,中间层都要决定是使用以前请求的缓冲值响应,还是传递请求。服务使用 XQuery 根据对服务请求元数据查询的结果描述判定缓冲是否有效。

posted @ 2006-04-17 02:16 wsdfsdf 阅读(192) | 评论 (0)编辑 收藏

SOA 反模式-----成功采用和实现面向服务的体系结构的障碍

了解不同的面向服务的体系结构 (SOA) 反模式,这些反模式对通常出现的会产生确定性负面结果的情形或解决方案进行了描述。随着越来越多的企业开始大举从 Web 服务转向 SOA,引入、采用和成功实现 SOA 方面的各种障碍变得越来越明显。其中一些障碍与导致过去的关键活动失败的因素类似;而其他障碍则是 SOA 特有的。对这些障碍和最差实践进行记录,将帮助顾问、架构师和专业人员不再犯同样的错误,并学习如何避免这些问题的发生。此处汇集和说明的反模式是由作者通过作为 IBM 架构师的个人经验、研究过去和当前的 SOA 应用案例以及通过分析那些参与客户 SOA 应用的技术先驱提供的信息而得到的。

模式与反模式

“示例不是另一种学习的方法,而是学习的唯一方法。”——阿尔贝特·爱因斯坦

模式和模式语言捕获并正式地将良好设计和基于经验的最佳实践系统化,以供其他人员对其进行重用。它们成功而清楚地表述了常见问题及其解决方案。总的来说,常见概念、描述这些概念的词汇以及将其联系在一起的语言是所有采用这些设计和实践的学科和领域的基础。

Christopher Alexander 关于建筑物和城市设计的研究通常被认为是基于模式的思维最早的成果(请参阅参考资料)。他提出了术语“模式语言”,以此代表他认为人类进行设计的能力和使用语言的能力都是天生的这一信念。

很多学科都在使用模式和模式语言的概念,包括从生理学和流程到项目管理和软件工程等领域。在 Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides(经常将他们称为 Gang of Four)的“Design Patterns: Elements of Reusable Object-Oriented Software”一书出版后,软件设计模式得到了广泛的认可和使用。

软件社区目前正使用模式来解决在软件生命周期中遇到的不断重复的问题,包括软件体系结构和设计,以及近来的软件开发流程和拓扑。这些模式全面捕获了一个知识体系,以标识我们对可以实现设计良好的软件解决方案的结构和机制的理解。

模式经常被定义为“泛型化的、命名的问题到解决方案的映射”。它捕获在特定环境中重复出现的问题的成功解决方案。

通常使用与表 1“模式模板”中描述的模板类似的模板来记录软件模式。


表 1. 模式模板
内容 说明
名称: 用于进行标识的名称
问题: 在领域中重复出现的问题
解决方案: 该问题的最佳实践解决方案
结果: 所建议的解决方案的优点和缺点
示例 一些已经应用了所建议的解决方案的示例

软件模式提供了一个在架构师和设计人员中捕获知识和经验的机制。它们提供了一种公共语言,可促进对其他地方成功应用的方法的重用,从而为软件项目带来以下方面的好处:风险更低、质量更好且交付时间更短。

而在另一方面,反模式则记录出现错误的情况。对数百个软件开发项目的各种调查勿庸置疑地证明了软件开发会出现错误(实际上经常是这样)。研究表明每六个项目中就有五个会不成功:交付远远超过预期预算、严重滞后或被取消。这就表明可能(至少)值得投入精力研究一下老是失败而很少成功的原因(注意 Bitter Java 的作者 Bruce Tate 在他的 developerWorks 文章中说明了为什么反模式是设计模式的必要和互补的同伴——有关更多信息,请参阅参考资料)。

应该对这些重复失败的软件开发项目或“反解决方案”加以研究,以收集关于出现了什么问题以及为什么会这样的有用知识。很显然,只对错误的原因进行分类并不一定非常有用,而还应研究如何加以避免以及出现时如何恢复。系统化后,这个知识集合可以提供软件模型的有价值的扩展(归类为反模式)。

反模式 使用非常频繁,但主要是问题的无效解决方案。这个术语最初是用于指示设计模式出现了错误。与模式类似,反模式的使用也扩展到了软件开发的各个阶段,并深入到了其他领域中。反模式记录常见的对效率有负面影响的重复解决方案。它们通常捕获重构解决方案描述,说明如何更改反模式,以得到更为稳定的解决方案。反模式通常使用模板进行描述,在其中标识症状、结果、根本原因和可能的解决方案。尽管与模式相比,反模式的研究并不很广泛,相关文档也不多,但软件领域对其中一些具有引人瞩目的反模式(如分析停顿、Blob、意大利面条式代码和“烟囱”系统)已耳熟能详。表 2 提供了一些这些示例的概述,这些示例均摘自 Brown 等的关于反模式的书中(有关更多信息,请参阅参考资料部分)。


表 2. 已知反模式的示例
错误类别 反模式 描述
设计 Blob 一个大型类具有太多的属性,且是系统的“核心”所在
设计 Poltergeists 非必要类且抽象过多
结构 意大利面条式代码 程序代码没有结构(很多 goto 语句)
结构 “烟囱”系统 应用程序是唯一的也是孤立的
技术 Wolf ticket 声明具有开放性的技术并与标准测试不相符
技术 不断退化模式 试图使用最新的版本
重用 剪切与粘贴 软件错误被复制
重用 Golden hammer 强制所有内容适应一个选定的工具

反模式为什么重要?反模式是用于防止问题的工具,可在问题出现之前对其进行标识,并能提供关于如何防止其发生的知识。通过将错误原因正式地系统化,我们可以更容易对其加以理解。一旦出现问题,反模式可以提供帮助,能说明如何从其进行恢复。

简要总结一下,反模式包括以下元素:

  • 关于不能工作的方案的记录
  • 常见术语表
  • 详细的修复方法
  • 环境的描述和备选解决方案
  • 可能成为将来的反模式的热门解决方案

图 1 说明了模式和反模式之间的区别。模式从试图解决的问题开始,记录针对此问题的可重复成功解决方案。此解决方案可带来一些好处、相应的结果以及可能会有一些问题。反模式说明对效率具有负面影响的常用的问题解决方案。它描述导致出现问题的原因,并说明如何防止或对解决方案进行修正。


图 1. 模式与反模式(摘自 Brown 等的“AntiPatterns: Refactoring Software, Architectures, and Projects in Crisis”)
模式与反模式





SOA:简要介绍

在过去五年中,有大量的文章谈面向服务、SOA,而最近几乎所有的东西都可以面向服务了。但我们所说的服务和面向服务到底指什么?

有很多不同的定义,而这些定义在不断地发生变化,以反映行业和 SOA 实践的成熟。我们将在此给出一些本文中将要使用的基本定义。这些定义在图 2 中得到了反映。


图 2. SOA 的定义
SOA 的定义
  1. 首先,什么是服务?服务是业务任务的可重复逻辑表现形式。此处有必要强调的是,我们所谈的是业务流程的一部分,而不是软件或 IT 的一部分。

    通过技术实现后,“服务”这一术语则应用到使用外化规范的软件资源(可发现的)。此服务规范可以供服务使用者进行搜索、绑定和调用。服务提供者对服务规范实现进行实现,并向服务使用者交付服务质量要求。服务将由声明性策略进行控制,因此支持可动态重新配置的体系结构样式。

  2. 第二,什么是面向服务?以我们的服务定义为基础,面向服务是一种将业务作为一组相关联的服务集成的方式。我们谈的仍然不是技术;我们谈论的是一种看待业务及其操作方式的新方法。
  3. 什么是 SOA?SOA 是一种支持面向服务的体系结构样式。SOA 是一种用于根据需要对资源进行关联的企业级 IT 体系结构。这些资源被表示为与业务一致的服务,这些服务可以参与和包含到价值网、企业或业务线中,以满足业务需求。
  4. 最后,什么是组合应用程序?它是一组集成的服务。组合应用程序是为了支持业务的各项功能而装配和组合到一起的实际运行的服务。SOA 应用程序的主要结构化元素是服务,而不是子系统、系统或组件。






标识 SOA 反模式的方法

SOA 反模式是通过使用以下方法标识的:

  • 已发布反模式的调查文献
  • 作者在与客户会谈中发现而记录下的反模式
  • 通过调查 SOA CoE 和 CoP 成员的经验而得到的反模式
  • 已使用的被认可的反模式模板/语言
  • 本文中包含的得到了三位作者一致认可的反模式

反模式模板/语言

反模式是使用以下模板/语言进行描述的:

  • 名称

    可表达反模式的特征的简洁名称

  • 问题/错误解决方案

    与反模式相关的经常出现的错误或错误解决方案

  • 症状

    问题的表现或标志

  • 结果

    应用此反模式的结果

  • 根本原因

    此项提供反模式的环境,即模式应用不正确而导致问题或解决方案失败的情况

  • 建议的解决方案

    可以解决问题并确保能带来更多好处的重构解决方案

SOA 反模式

已标识的反模式分为三类:

  1. SOA 采用反模式:此类为阻碍或延迟客户和业务的 SOA 采用进程的反模式。讨论的属于此类的反模式有:
    • A1. 技术跟风
    • A2. 老调重谈
    • A3. 大爆炸
  2. 服务标识和设计反模式:此类反模式是技术先驱在作为 SOA 活动的一部分对服务进行标识和设计时遇到的反模式。讨论的属于此类的反模式有:
    • I1. Web 服务 = SOA
    • I2. 竖井( Silo) 方法
    • I3. 注册中心行为不正常
  3. 服务实现反模式:此类反模式捕获实现服务的最差实践。很多此类反模式主要关注 Web 服务实现(最常见的 SOA 实现)。在本文中,我们给出的是不关注 Web 服务的 SOA 实现反模式的部分列表,因为对于以 Web 服务为中心的 SOA 实现反模式在 Web 服务专门论坛上已经进行了大量的讨论。讨论的属于此类的反模式有:
    • R1.通信较多的服务
    • R2.点到点服务
    • R3.无组件的服务

随着 SOA 越来越成熟,其应用越来越多,则有希望标识越来越多的反模式。


表 3. 反模式列表
类别 ID 反模式 描述
采用-A1 技术跟风 一种非常值得注意的常见趋势,在此情况下,企业决定采用流行的新技术,而没有仔细考虑此技术是否对业务有所帮助。
采用-A2 老调重谈 缺乏对 SOA 和以前的计算范例之间区别的了解,从而使其提出置疑,认为 SOA 不过是同样的旧技术的一个名称而已。结果是,即使采用 SOA 能为业务带来好处,也反对采用它。
采用-A3 大爆炸 此反模式也称为“囫囵吞枣”。当将 SOA 视为万能的,而立即对所有企业系统和体系结构进行全面更改时,采用的就是此反模式。这样急于求成地采用 SOA 会导致一些会不公平地归咎于 SOA 的错误。
标识和设计-I1 Web 服务 = SOA 当架构师将 SOA 与 Web 服务划上等号时,他们实际上在冒险,可能会使用不具有合适体系结构的 Web 服务替换现有 API。这样将导致标识很多与业务不一致的服务。
标识和设计-I2 竖井方法 在此反模式中,服务是根据独立的应用程序标识的,因此不同的小组可能会使用不同的名称标识同样的服务。因此,不能实现公共服务或服务共享。
标识和设计-I3 注册中心行为不正常 重复的服务注册表项,所属关系重复、不清楚,从而由于重复而导致管理灾难和运行时混淆、潜在的性能低下和计划外成本。
实现-R1 通信较多的服务 此反模式描述了一个常见错误,开发人员在通过实现很多 Web 服务(这些服务彼此需要就一小部分数据进行通信)而实现服务时,通常可能犯这个错误。这将导致实现大量服务,从而导致性能下降,开发成本增加。
实现-R2 点到点的服务 在应用程序间使用 XML 或 SOAP over HTTP 代替点到点 Web 服务的中间件,将导致点到点集成的出现,而成为事实上的集成模式。
实现-R3 无组件的服务 不清楚与所属组件关联的情况下就直接进行 Web 服务的开发和实现,将会导致未结构化、不受约束的体系结构(没有严格的分层机制)。这将导致服务接口后端和保留现有应用程序和软件包的遗留限制方面的灵活性低下。






SOA 采用反模式

这些是阻碍或延迟客户和业务的 SOA 采用进程的反模式。

A1:反模式名称:技术带宽(另请参阅:Web 服务 = SOA)

  • 问题

    我们发现,很多公司从 IT 的角度开始着手 SOA 工作,而不是从业务角度看待问题。实现可能从技术角度而言是可行的,有时候也能成功,但由于首先没有考虑业务,因此其对业务的影响可能无法实现。

  • 环境

    此反模式主要出现在建立了良好的 IT 部门的大型企业中,此部门主要雇佣的是技术人员,决策方面受到技术层面的影响更多。

  • 症状

    此反模式的常见症状表现为发起人不能清楚地阐释采用 SOA 的价值主张。此外,另一个症状可能表现为缺乏针对 SOA 实现的业务/项目一致性。

  • 结果

    由于此反模式,IT 成本将会上升,却没有实现任何投资回报 (ROI)。此外,公司可能会失去为 IT 投资组合注入灵活性的机会。

  • 根本原因

    在大多数情况下,此反模式的根本原因在于,为了赶上通过采用此技术可能实现领先地位的竞争者所宣称的能力,公司因此而承受压力。由于这个原因,公司可能发现开展基于技术的工作来引入 SOA 更为容易,而不会花时间和精力将其与业务需求结合。

  • 解决方案

    处理此反模式的最佳方法是建立没有浮夸的 SOA 价值主张,可以通过标识和描述特定于客户的难点或业务挑战来实现这一点。此方法可以通过开发用于在业务的支持下恰当地引入技术的路线图来进行互补。

  • 解决方案示例:根据没有浮夸的 SOA 价值主张开发 SOA 平台

    一家全球汽车租赁公司了解可支持其关键业务动力的 SOA 解决方案的价值主张:

    • 可提供一个灵活的业务模型,以提高交付新业务服务的速度和灵活性
    • 通过简化流程来降低操作成本,从而使成本下降
    • 通过为其客户提供率先推向市场的创新服务来缩短外部业务流程的周期和成本
    • 通过允许方便灵活的集成来支持多个交付渠道,从而在整个企业范围内进行集成

A2:反模式名称:老调重谈

  • 问题

    此反模式描述的情况是这样的:公司置疑 SOA 不过是相同的旧技术的一个名称而已,SOA 并不能提供任何它们尚未提供的新功能。从表面上来看,似乎可能是这样,但过去已经提供的功能和通过恰当实现 SOA 可以提供的功能相比,Web 服务和 XML(以及其他相关的标准)的出现则是一个重大的区别。

  • 环境

    这个反模式主要出现在那些习惯其已经长期使用的技术,而不愿意引入或考虑进行改变的 IT 专业人员身上。当 IT 部门经历了大费周折的技术转换后,或新技术并不能实现最初的承诺时,也可能出现此反模式。

  • 症状

    最明显的症状就是公司中的一些技术管理人员强烈反对将 SOA 作为处理合法业务问题的正式方法。反对可表现为强烈而明显的争辩,反对采用 SOA;或者可以表现为隐含的被动的方式,在讨论业务问题的解决方案时完全忽略 SOA。

  • 结果

    此反模式很可能会导致缺乏 SOA 支持,而最终会导致失去实现将支持业务难点的 SOA 价值主张的机会。

  • 根本原因

    尽管 SOA 构建于其他计算范例(例如,面向对象和基于组件的开发)所引入和支持的相同原则之上,很多有经验的 IT 团队仍然不能真正理解 SOA 与这些其他计算范例之间的区别。缺乏理解是此反模式的一个基本根源。另一个根本原因则是 IT 团队在实现太多的“范例转换”方面的经验不丰富(而不愿尝试新的技术)的直接结果。

  • 解决方案

    处理此反模式的一个方法就是强调 SOA 与早期解决方案的不同之处。例如,应对 API 和服务之间的区别加以讨论,应对开发标准依赖性及其区别属性进行说明。另一个主要不同点在于作为 SOA 主要组件的企业服务总线 (ESB) 的出现。ESV 提供的工具(如传输服务、中介服务和事件服务)就是一些通过采用 SOA 所提供的新服务的例子。不过,最有效的解决方案则是提供一些成功的示例,以突出区别和演示实现 SOA 解决方案的成功案例和可行性。

  • 解决方案示例:SOA 培训

    对业务部门和 IT 部门进行培训,阐释 SOA 的概念、其价值主张,并说明其在提供支持业务所需的 IT 灵活性方面的好处。促进对 Web 服务和 XML 标准及实现 SOA 中的新兴标准的重要性的理解,这些内容正是 SOA 与过去的范例转换的不同之处。

A3:反模式名称:大爆炸(也称为:囫囵吞枣)

  • 问题

    此反模式可以看作“老调重谈”反模式的对立面。此处的问题在于,支持者将 SOA 视为万能的,而立即对所有企业系统和体系结构进行全面更改。

  • 环境

    此反模式和“技术跟风”反模式的环境一样。特别在其主要股东具有很强的技术背景,且比对应的业务方面的人员更有影响力的企业中,他们就很可能会采用“囫囵吞枣”的方式,而完全不考虑对业务的影响。

  • 症状

    如果业务单位对采用 SOA 所带来的更改十分担心,则清楚地表明此采用了此反模式。

  • 结果

    应用此反模式后,将会出现严重的错误,无法提供 SOA 所承诺的好处(可以从现有体系结构获得回报),从而延迟(甚至消除) SOA 所具有的任何潜在优势。采用此反模式的另一个结果就是可能会将任何交付错误归咎于 SOA,而不是查找问题的根本原因。

  • 根本原因

    任何企业中的狂热技术支持者都可能是此类反模式的根源所在,特别在这些技术支持者处在可以优先于业务考虑做出 IT 决策。

  • 解决方案

    为了消除此反模式,一种解决方案是指定一个业务支持路线图,以采用增量的方式逐步采用 SOA。不要采用试图通过使用 SOA 进行全面更改的方式解决所有企业问题,更好的做法是首先构建一个试验性业务案例,当试用成功后,则使用路线图选择下一个可能从 SOA 获益的目标业务领域。如果可为组织中那些负责 SOA 推广的人员提供 SOA 入门培训,也将十分有用。

  • 解决方案示例:开发实现 SOA 的路线图。

    一家大型银行在考虑到其业务策略后,确定其正确的体系结构方向是 SOA 解决方案,此解决方案可以帮助其实现其业务目标。该银行首先对其服务集成方面的成熟度水平进行了评估。然后,开发了路线图来帮助银行以增量的方式迁移到 SOA 环境,以在继续提供必要的业务功能的同时最小化风险。该银行选择了一个试验性项目来验证 SOA 体系结构样式,并找出在迁移到 SOA 范例过程中可能出现的任何技术和组织问题。







SOA 标识和设计反模式:

此类反模式是技术先驱在作为 SOA 活动的一部分对服务进行标识和设计时遇到的反模式。

I1:反模式名称:Web 服务 = SOA(也称为服务增殖综合症)

  • 问题

    对于很多人而言,SOA 不过是 Web 服务的另一个名称而已。尽管实现 Web 服务是采用 SOA 过程中的一个合理的入口点,但企业不应将 Web 服务和 SOA 划上等号。

  • 环境

    目前的大部分生产 Web 服务系统都不是 SOA。它们只是通过 SOAP 或结构良好的集成体系结构的远程过程调用或点到点消息传递而已。各种组织发现,通过仅实现 Web 服务而宣称迁移到 SOA 的方式更为简单。

  • 症状

    在不采用恰当的体系结构的情况下使用 Web 服务替代 API,并实现不与业务一致的服务是此反模式的明显症状。

  • 结果

    Web 服务的增殖是应用此反模式的直接结果。这个结果是将任何接口都作为 Web 服务实现,而不管这些服务是否是 SOA 价值主张的一部分而造成的。另外,最终的系统也可能没有反映服务请求方要求的接口。

  • 根本原因

    此反模式的根本原因有两种。首先是操之过急,意在走捷径,以快速廉价的方式开展 SOA 方面的工作。其次是缺乏对 SOA 和 Web 服务的区别的认识,不理解对好的服务建模技术的需求。

  • 解决方案

    处理此反模式的一个方法是制定可行的 SOA 转换计划,此计划要求组织对其 SOA 价值主张进行定义。实现 SOA 价值主张要求同时使用 SOA 和 Web 服务。这将要求对 SOA 和 Web 服务的区别进行培训,并应用好的服务建模方法,如面向服务的建模和体系结构(Service-Oriented Modeling and Architecture,SOMA)。

  • 解决方案示例:应用服务建模以标识粗粒度的服务和将 Web 服务作为 SOA 解决方案的实现技术加以利用

    引入和采用良好的服务建模技术来确定供业务解决方案使用的恰当粗粒度服务,并利用 Web 服务来实现 SOA 解决方案。恰当服务粒度水平将帮助尽可能减少过分细粒度服务的增加。实现 SOA 价值主张要求同时使用 SOA 和 Web 服务。

I2:名称:竖井方法

  • 问题

    此反模式带来的问题是标识服务的方式。当根据独立的应用程序(而不是以企业策略为中心)对服务进行标识时,期望 SOA 实现所带来的好处将永远不能实现。

  • 环境

    此反模式主要出现在根据独立工作的具有塔状结构的功能模型进行组织的企业中。每个功能塔所享有的自治权将导致采用竖井方式进行工作。

  • 症状

    此反模式的一个症状是不同的小组使用不同的名称对相同的服务进行标识。没有标识公共服务,或未实现服务共享,同样也清楚地表明应用了此反模式。

  • 结果

    由于采用竖井(silo)方法会导致服务被多次标识和实现,不必要的昂贵开发成本或服务重复使得采用 SOA 所能带来的好处大打折扣。而且,由于使用此反模式,会使不同应用程序的受益人间的重用减少或完全消失。

  • 根本原因

    在大多数情况下,组织的边界和约束是此反模式的根本原因。在某些企业中,缺乏对“服务公开决策”的有所控制的方法也是根本原因。

  • 解决方案

    此反模式的解决方案是建立一个控制框架,以确保跨功能塔进行服务标识和通信。另外,还应当进行以标识公共服务为目的的相关工作。这可以通过使用 SOMA 等好的服务建模方法来完成。

  • 解决方案示例:标识公共服务

    像大多数企业一样,一家大型银行是按照业务塔进行的组织,这些业务塔为不同类型的银行客户提供类似的业务功能。SOMA 用于开发服务模型,以促进业务塔间的重用和了解此类重用机会。从更高的角度来看,在支持业务功能所需的业务服务中,约有 90% 都具有相似性,这是潜在的重用领域。

I3:反模式名称:注册中心行为不正常

  • 问题

    在没有一致的 SOA 控制模型的情况下采用 UDDI 将导致流程和设计的效率低下。特别是重复的注册中心可能导致效率低下,使得性能下降,并可能产生安全和遵从性漏洞。

  • 环境

    没有注册中心控制协议,但却尝试建立 UDDI 用途的企业将经常遇到此反模式。

  • 症状

    考虑到 UDDI 是标准而不是产品,如果使用不恰当,可能导致建立重复的服务注册中心和重叠的、不明确的关系。这将表现为不正确的、容易引起误会的服务接口信息,特别在共享服务模型内的组合服务场景的发现操作期间表现得十分明显。尽管注册中心中单个服务接口的描述是正确的,但重复的条目将导致整个服务的发现不正确。而且,缺乏控制模型可能是由于服务在生命周期流程的各个阶段注册,当不具有一对一的所属关系转换时被遗弃而造成的。例如:假定某个开发人员向内部 UDDI 添加了三个服务。然后,服务管理员可能会将其中两个迁移到生产 UDDI 中。这就产生了孤立服务。服务组件也可能出现类似的情况。

  • 结果

    在试图确定注册中心中哪个服务导致无法满足 SLA 时,重复的注册中心将导致控制灾难和运行时混淆。此外,此类重复还会导致性能下降和安全漏洞及遵从性漏洞。此类反模式的另一个结果就是由于重复而会产生计划外成本。

  • 根本原因

    缺乏设计时一致性(SOA 控制模型)是导致此反模式的主要原因。具体来说,此问题的核心是服务注册中心所属关系不清楚且没有建立和执行企业级 SOA 参考体系结构。

  • 解决方案

    为了避免此反模式,公司必须建立 SOA 控制模型,以定义和采用服务注册中心最佳实践、所属关系以及相关团队间的通信。这将消除重复条目和不正确的接口信息,并最小化包含孤立服务的结果。由于只有一个服务描述源(其中包含关联的 SLA 和策略),因此还可以消除运行时混淆。使用 SOA 企业级参考体系结构间建立和执行遵从性应是 SOA 控制模型制度化的第一步。







SOA 实现反模式

此类反模式捕获实现服务的最差实践。

R1:反模式名称:通信较多的服务

  • 问题

    此反模式描述开发人员通过实现一系列 Web 服务(这些服务彼此需要就一小部分数据进行通信)来实现服务的情况。同一个反模式的另一表现是服务实现最后会进行大量的微型信息通信,而不是采用将数据组合到全面的类似于文档的格式中。

  • 环境

    如果组织中的开发人员急于在没有恰当的建模的情况下开始进行实现,这些组织将最终受到此反模式的困扰。在某些情况下,开发人员被要求在没有了解如何从 SOA 获得最大利益的情况下使用 Web 服务替代 API,将通常会导致此反模式。

  • 症状

    如果有实现大量过分细粒度服务的需求,则表明应用了此反模式。

  • 结果

    性能下降和开发成本增加是此反模式的主要结果。此外,使用者必须进行额外的工作以对这些过分细粒度的服务进行聚合,以实现相关优势和获得如何将这些服务一起使用的知识。

  • 根本原因

    由于不知道任何更好的办法,很多开发人员采用的方法就是采用 Web 服务的形式模拟 API 的实现。这与我们在最开始采用面向对象的编程技术时的情况(开发人员使用面向对象的语言来开发过程型的程序)十分相似。另外,急于采用这项新技术,可能会导致所有内容都成为 Web 服务,却不能带来任何好处,而且成本会急剧增加。

  • 解决方案

    为了避免此反模式,需要集中精力进行设计重构,以将各个数据片断组合到一个文档中,以消除通信量过多的服务。另外,就 API 和服务之间的区别进行培训(并强调恰当的服务粒度),也会有用。不过,避免此反模式的最有效办法是定义映射回业务目标的服务。可以通过引入和使用好的服务建模技术来为业务解决方案确定恰当的粗粒度服务,从而完成此工作。这将最小化服务通信过多的行为,因为此行为已在 SOA 中正确的粒度级别得到了标识。应用 Service Litmus Test (SLT) 也可以帮助确定要公开的正确服务级别。SLT 的一个例子是考虑服务是否提供了支持业务流程和目标所需的业务功能单元。

R2:反模式名称:点到点服务

  • 问题

    基本问题是开发人员在不考虑使用环境的情况下尝试使用点到点 Web 服务作为集成方法替代中间件。

  • 环境

    此模式出现在缺乏长期系统集成远景而强调短期结果的组织中。

  • 症状

    此反模式的一个表现是在内部应用程序之间使用 SOAP over HTTP。

  • 结果

    由于使用此反模式,点到点集成解决方案将作为企业的事实上的集成模式出现。这将对任何实现恰当 SOA 实现的所有优势的可能带来负面影响。

  • 根本原因

    此模式的主要根源是缺乏对总体系统的长期维护和发展的考虑(可能是由于强调短期解决方案而造成的)。在某些情况下,急于在别处使用服务也可能导致此类点到点服务方法使用的增多。

  • 解决方案

    为了避免采用此反模式的结果,应该考虑将智能连接器(如服务总线)作为正式集成方法使用。使用服务总线,应用程序可以简单有效地一起工作,以支持业务需求,并同时保持协作系统和应用程序间的松散耦合。

  • 已知的例外情况

    有一些例外的情况,在这些情况下此反模式解决方案是可以接受的。例如,为了解决即时的业务问题以及可以使用点到点服务的情况下,就需要采用快速的短期集成方案。不过,这些解决方案有可能会在生产中长时间存在。因此,应用此反模式时应当小心地进行监视,并应当配备相应的控制,以防止长期采用此反模式。

R3:反模式名称:无组件的服务(也称为“逻辑分层已过时”)

  • 问题

    用于服务建模的最佳实践将促进已标识的服务与其所属的组件相关联。此反模式带来的问题是,开发人员趋于在没有与所属组件明确关联的情况下直接进行 Web 服务的开发和实现。

  • 环境

    此反模式出现在体系结构模式未得到应用或考虑的环境中,例如,分层体系结构模式。缺乏体系结构规则使得环境极易出现此类反模式的应用。

  • 症状

    对服务进行检查,将会发现系统可以在不遵循任何体系结构的结构要求就可以直接达到系统的任何部分。在这些情况下,Web 服务是在不考虑任何分层和分离概念的情况下开发的。

  • 结果

    最值得注意的结果是服务接口之外非常不灵活,因为模块设计、信息隐藏和逻辑结构原则均未得到遵循。这将导致仍然保留了现有应用程序和软件包的遗留限制,从而可能导致在将来不能进行重新设计。

  • 根本原因

    与违反了最佳操作的任何其他情况一样,此反模式的根本原因在于缺乏良好的设计。

  • 解决方案

    组件和 SOA 的真正潜能仅在同时具有两者的情况下才能实现。解决的办法是采用由基于组件的灵活应用程序支持的一致服务接口。这将要求开发人员继续利用 J2EE 和常见 EAD 最佳实践及分层模式,将其作为克服此反模式的缺陷的方法。

  • 解决方案示例:理解组件对于 SOA 的价值

    服务最好使用组件实现。如果没有组件,服务接口后端就没有灵活性可言,并可能要担心实现的可伸缩性和可移植性。现有应用程序和软件包将保留其遗留限制,这将最大程度降低地提供支持不断变化的业务需求所需的灵活性的能力。组件可使用其松散耦合和重用功能提供支持服务接口所需的可伸缩性和灵活性。






总结

在本文中,我们了解了一些通过观察所得的 SOA 反模式,并介绍了一些影响 SOA 的采用、标识和设计及实现的 SOA 项目。

posted @ 2006-04-17 02:14 wsdfsdf 阅读(139) | 评论 (0)编辑 收藏

仅列出标题
共19页: First 11 12 13 14 15 16 17 18 19