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

架构设计师与 SOA , 第 2 部分

本系列的第 1 部分 介绍了有关架构设计师以及 SOA 架构的知识,分析了 SOA 架构师在设计 SOA 系统架构时有哪些应该特别注意的地方。本文将延续第一部分的内容,向您介绍了 SOA 为企业级架构设计带来的影响,以及在构建基于 SOA 架构的企业系统时应该怎样保证所构建的系统架构能够满足系统中不同的服务级别需求。

1. SOA 为企业级架构设计带来的影响

1.1 SOA 的特点及其使用范围

SOA 既不是一种语言,也不是一种具体的技术,它是一种新的软件系统架构模型。 SOA 最主要的应用场合在于解决在Internet环境下的不同商业应用之间的业务集成问题。Internet环境区别于Intranet环境的几个特点主要是:

(a)大量异构系统并存,不同计算机硬件工作方式不同,操作系统不同、编程语言也不同;

(b)大量、频繁的数据传输的速度仍然相对较缓慢并且不稳定;

(c)无法完成服务(service)的版本升级,甚至根本就无法知道互联网上有哪些机器直接或者间接的使用某个服务。

SOA 架构具有一些典型特性,主要包括松耦合性,位置透明性以及协议无关性。松耦合性要求 SOA 架构中的不同服务之间应该保持一种松耦合的关系,也就是应该保持一种相对独立无依赖的关系;位置透明性要求 SOA 系统中的所有服务对于他们的调用者来说都是位置透明的,也就是说每个服务的调用者只需要知道他们调用的是哪一个服务,但并不需要知道所调用服务的物理位置在哪里;而协议无关性要求每一个服务都可以通过不同的协议来调用。通过这些 SOA 架构所具有的特性我们可以看到,SOA 架构的出现为企业系统架构提供了更加灵活的构建方式,如果企业架构设计师基于 SOA 来构建系统架构,就可以从底层架构的级别来保证整个系统的松耦合性以及灵活性,这都为未来企业业务逻辑的扩展打好了基础。

1.2 SOA 架构的分层模型

接下来简要介绍一下 SOA 系统中的分层模型,整个 SOA 架构的分层模型如图2所示。



在 SOA 系统中不同的功能模块可以被分为7层:第一层就是系统已经存在的程序资源,例如ERP或者CRM系统等。第2层就是组件层,在这一层中我们用不同的组件把底层系统的功能封装起来。第3层就是 SOA 系统中最重要的服务层,在这层中我们要用底层功能组件来构建我们所需要的不同功能的服务。总的来说,SOA 中的服务可以被映射成具体系统中的任何功能模块,但是从功能性方面可以大致划分为以下三种类型:(1)商业服务(business service) 或者是商业过程(business process)。这一类的服务是一个企业可以暴露给外部用户或者合作伙伴使用的服务。比如说提交贷款申请,用户信用检查,贷款信用查询。(2)商业功能服务(business function service), 这类服务会完成一些具体的商业操作,也会被更上层的商业服务调用,不过大多数情况下这类服务不会暴露给外部用户直接调用,比如说检索用户帐户信息,存储用户信息等。(3)技术功能服务(technical function service),这类服务主要完成一些底层的技术功能,比如说日志服务以及安全服务等。在服务层之上的第4层就是商业流程层,在这一层中我们利用已经封装好的各种服务来构建商业系统中的商业流程。在商业流程层之上的就是第5层表示层了,我们利用表示层来向用户提供用户接口服务,这一层可以用基于portal的系统来构建。以上这5层都需要有一个集成的环境来支持它们的运行,第6层中的企业服务总线(ESB)提供了这个功能。第7层主要为整个 SOA 系统提供一些辅助的功能,例如服务质量管理,安全管理这一类的辅助功能。







2. SOA 架构中的非功能性服务级别(service-level)需求

除了系统的业务需求,架构设计师还必须要保证构建出来的系统架构能够满足系统中的非功能性服务级别(service-level)需求以及服务质量(QoS)方面的需求。在项目初始及细化阶段,架构设计师应该与系统所有涉及方(Stakeholders)一起,为每一个服务级别需求定义其相关的衡量标准。构建出的系统架构必须要能满足以下几方面的服务水准要求:性能、可升级性、可靠性、可用性、可扩展性、可维护性、易管理性以及安全性。架构设计师在设计架构过程中需要平衡所有的这些服务级别需求。例如,如果服务级别需求中最重要的是系统性能,架构设计师很有可能不得不在一定程度上牺牲系统的可维护性及可扩展性,以确保满足系统性能上的要求。随着互联网的发展,新构建的系统对于服务级别需求也变得日益重要,现在基于互联网的企业系统的用户已经不仅仅局限于是本企业的雇员,企业的外部客户也会成为企业系统的主要用户。

架构设计师的职责之一就是要尽可能地为提高系统设计人员和系统开发人员的工作效率考虑。在构建整个企业系统架构的过程中,需要充分重视各种服务级别需求,从而避免在系统开发和运行的时候出现重大问题。一个企业级系统中的服务级别需求往往是十分错综复杂的, SOA 架构设计师需要凭借丰富的专业经验和扎实的理论知识来分离和抽象系统中不同的服务级别需求,图3展示了这种分析的过程。


图3
图3

经过 SOA 架构设计师分析和抽象的服务级别需求主要分为以下几类:

  • 性能是指系统提供的服务要满足一定的性能衡量标准,这些标准可能包括系统反应时间以及处理交易量的能力等;
  • 可升级性是指当系统负荷加大时,能够确保所需的服务质量,而不需要更改整个系统的架构;
  • 可靠性是指确保各应用及其相关的所有交易的完整性和一致性的能力;
  • 可用性是指一个系统应确保一项服务或者资源永远都可以被访问到;
  • 可扩展性是指在不影响现有系统功能的基础上,为系统填加新的功能或修改现有功能的能力;
  • 可维护性是指在不影响系统其他部分的情况下修正现有功能中问题或缺陷,并对整个系统进行维护的能力;
  • 可管理性是指管理系统以确保系统的可升级性、可靠性、可用性、性能和安全性的能力;
  • 安全性是指确保系统安全不会被危及的能力。

1) 性能

我们通常可以根据每个用户访问的系统响应时间来衡量系统的整体性能;另外,我们也可以通过系统能够处理的交易量(每秒)来衡量系统的性能。对于架构设计师来说,无论采取哪种衡量系统性能的方法来构建系统架构,这些对于性能的考虑对系统设计开发人员来说都应该是透明的,也就是说对于系统整体架构性能的考虑应该是架构设计师的工作,而不是系统设计开发人员应该关注的事情。在较传统的基于EJB或者XML-RPC的分布式计算模型中,它们的服务提供都是通过函数调用的方式进行的,一个功能的完成往往需要通过客户端和服务器来回很多次的远程函数调用才能完成。在Intranet的环境下,这些调用给系统的响应速度和稳定性带来的影响都可以忽略不计,但如果我们在基于 SOA 的架构中使用了很多Web Service来作为服务提供点的话,我们就需要考虑性能的影响,尤其是在Internet环境下,这些往往是决定整个系统是否能正常工作的一个关键决定因素。因此在基于 SOA 的系统中,推荐采用大数据量低频率访问模式,也就是以大数据量的方式一次性进行信息交换。这样做可以在一定程度上提高系统的整体性能。

2) 可升级性

可升级性是指当系统负荷加大时,仍能够确保所需的服务质量,而不需要更改整个系统的架构。当基于 SOA 的系统中负荷增大时,如果系统的响应时间仍能够在可接受的限度内,那么我们就可以认为这个系统是具有可升级性的。要想理解可升级性,我们必须首先了解系统容量或系统的承受能力,也就是一个系统在保证正常运行质量的同时,所能够处理的最大进程数量或所能支持的最大用户数量。如果系统运转时已经不能在可接受时间范围内反应,那么这个系统已经到达了它的最大可升级状态。要想升级已达到最大负载能力的系统,你必须增加新的硬件。新添加的硬件可以以垂直或水平的方式加入。垂直升级包括为现在的机器增加处理器、内存或硬盘。水平升级包括在环境中添置新的机器,从而增加系统的整体处理能力。作为一个系统架构设计师所设计出来的架构必须能够处理对硬件的垂直或者水平升级。基于 SOA 的系统架构可以很好地保证整体系统的可升级性,这主要是因为系统中的功能模块已经被抽象成不同的服务,所有的硬件以及底层平台的信息都被屏蔽在服务之下,因此不管是对已有系统的水平升级还是垂直升级,都不会影响到系统整体的架构。

3) 可靠性

可靠性是指确保各应用及其相关的所有交易的完整性和一致性的能力。当系统负荷增加时,你的系统必须能够持续处理需求访问,并确保系统能够象负荷未增加以前一样正确地处理各个进程。可靠性可能会在一定程度上限制系统的可升级性。如果系统负荷增加时,不能维持它的可靠性,那么实际上这个系统也并不具备可升级性。因此,一个真正可升级的系统必须是可靠的系统。在基于 SOA 来构建系统架构的时候,可靠性也是必须要着重考虑的问题。要在基于 SOA 架构的系统中保证一定的系统可靠性,就必须要首先保证分布在系统中的不同服务的可靠性。而不同服务的可靠性一般可以由其部署的应用服务器或Web服务器来保证。只有确保每一个 SOA 系统中的服务都具有较高的可靠性,我们才能保证系统整体的可靠性能够得以保障。

4) 可用性

可用性是指一个系统应确保一项服务或者资源应该总是可被访问到的。可靠性可以增加系统的整体可用性,但即使系统部件出错,有时却并不一定会影响系统的可用性。通过在环境中设置冗余组件和错误恢复机制,虽然一个单独的组件的错误会对系统的可靠性产生不良的影响,但由于系统冗余的存在,使得整个系统服务仍然可用。在基于 SOA 来构建系统架构的时候,对于关键性的服务需要更多地考虑其可用性需求,这可以由两个层次的技术实现来支持,第一种是利用不同服务的具体内部实现内部所基于的框架的容错或者冗余机制来实现对服务可用性的支持;第二种是通过UDDI等动态查找匹配方式来支持系统整体的高可用性。在 SOA 架构设计师构建企业系统架构的时候,应该综合考虑这两个方面的内容,尽量保证所构建的 SOA 系统架构中的关键性业务能具有较高的可用性。

5) 可扩展性

可扩展性是指在不影响现有系统功能的基础上,为系统添加新的功能或修改现有功能的能力。当系统刚配置好的时候,你很难衡量它的可扩展性,直到第一次你必须去扩展系统已有功能的时候,你才能真正去衡量和检测整个系统的可扩展性。任何一个架构设计师在构建系统架构时,为了确保架构设计的可扩展性,都应该考虑下面几个要素:低耦合,界面(interfaces)以及封装。当架构设计师基于 SOA 来构建企业系统架构时,就已经隐含地解决了这几个可扩展性方面的要素。这是因为 SOA 架构中的不同服务之间本身就保持了一种无依赖的低耦合关系;服务本身是通过统一的接口定义(可以是WSDL)语言来描述具体的服务内容,并且很好地封装了底层的具体实现。在这里我们也可以从一个方面看到基于 SOA 来构架企业系统能为我们带来的好处。

6) 可维护性

可维护性是指在不影响系统其他部分的情况下修改现有系统功能中问题或缺陷的能力。同系统的可扩展性相同,当系统刚被部署时,你很难判断一个系统是否已经具备了很好的可维护性。当创建和设计系统架构时,要想提高系统的可维护性,你必须考虑下面几个要素:低耦合、模块性以及系统文档记录。在企业系统可扩展性中我们已经提到了 SOA 架构能为系统中暴露出来的各个子功能模块也就是服务带来低耦合性和很好的模块性。关于系统文档纪录,除了底层子系统的相关文档外,基于 SOA 的系统还会引用到许多系统外部的由第三方提供的服务,因此如果人力资源准许的话,应该增加专职的文档管理员来专门负责有关整个企业系统所涉及的所有外部服务相关文档的收集、归类和整理,这些相关的文档可能涉及到第三方服务的接口(可以是WSDL)、服务的质量和级别、具体性能测试结果等各种相关文档。基于这些文档,就可以为 SOA 架构设计师构建企业 SOA 架构提供很好的文档参考和支持。

7) 可管理性

可管理性是指管理系统以确保整个系统的可升级性、可靠性、可用性、性能和安全性的能力。具有可管理性的系统,应具备对服务质量需求(QoS)的系统监控能力,通过改变系统的配置从而可以动态地改善服务质量,而不用改变整体系统架构。一个好的系统架构必须能够监控整个系统的运行情况并具备动态系统配置管理的功能。在对复杂系统进行系统架构建模时, SOA 架构设计师应该尽量考虑利用将系统整体架构构建在已有的成熟的底层系统框架(Framework)上。对于 SOA 架构设计师来说,可以选择的底层系统框架有很多,可以选用基于MQ, MessageBorker,WebSphere Application Server等产品来构建企业服务总线(Enterprise Service Bus)以支持企业的 SOA 系统架构,也可以选用较新的基于WebSphere Application Server 6中内嵌的Sibus来构建企业的ESB以支持 SOA 系统架构。具体选择哪种底层框架来实施 SOA 系统架构要根据每个系统各自的特点来决定,但这些底层的框架都已经提供了较高的系统可管理性。因此,分析并选择不同的产品或底层框架来实现企业系统架构也是架构设计师的主要职责之一。有关于如何利用已有底层架构来构建 SOA 系统,中国 SOA 设计中心已经发表了一系列相关的文章,大家可以在DeveloperWorks中的 SOA 专栏看到它们。

8) 安全性

安全性是指确保系统安全不会被危及的能力。目前,安全性应该说是最困难的系统质量控制点。这是因为安全性不仅要求确保系统的保密和完整性,而且还要防止影响可用性的服务拒绝(Denial-of-Service)攻击。这就要求当 SOA 架构设计师在构建一个架构时,应该把整体系统架构尽可能地分割成各个子功能模块,在将一些子功能模块暴露为外部用户可见的服务的时候,要围绕各个子模块构建各自的安全区,这样更便于保证整体系统架构的安全。如果一个子模块受到了安全攻击,也可以保证其他模块相对安全。如果企业 SOA 架构中的一些服务是由Web Service实现的,在考虑这些服务安全性的时候也要同时考虑效率的问题,因为WS-Security会为Web Service带来一定的执行效率损耗。







3.结束语

本系列两部分介绍了有关架构设计师以及 SOA 架构的知识,分析了 SOA 架构师在设计 SOA 系统架构时有哪些应该特别注意的地方并在最后简要介绍了在构建基于 SOA 架构的企业系统时应该怎样保证所构建的系统架构能够满足系统中不同的服务级别需求。从架构设计师的角度, SOA 是一种新的设计模式,方法学。因此, SOA 本身涵盖了很多的内容,也触及到了系统整体架构设计、实现、维护等各个方面。本文的内容只是涉及到了有关于架构方面的一部分内容,希望能对广大的 SOA 系统开发设计人员起到一定的帮助作用。

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

用于实现 Web 服务的 SOA 编程模型,第 5 部分: 面向服务的用户界面

面向服务的编程模型可以简化程序到用户 (program-to-human) 的交互的开发,方法是在用户或者管理员控制下在表示层抽象化接口、标准化消息以及聚合独立信息源。本文是关于 IBM 的 SOA 编程模型的系列文章的第 5 部分,介绍了用户面对的服务并提供了用户界面 (UI)。本系列前面的文章介绍了与语言无关的数据访问和基于面向服务的体系结构(Service-Oriented Architecture,SOA)概念的 Web 服务的编程模型。

面向服务的体系结构的用户界面

在文献中,对 Web 服务的讨论通常是在程序到程序 (program-to-program) 交互的上下文中进行的。然而,

模型-视图-控制器(Model-View-Controller,MVC)范例是现代大多数 UI 应用程序框架的基础。SOA 操作提供模型层,而 UI 位于视图层。UI 技术可以在各种设备上呈现信息,这些设备包括的范围很广,从窗口小部件和智能电话到浏览器和能够进行大量客户端处理的富客户机。中间件和工具将视图层 UI 技术连接到模型层 Web 服务和数据。

在 SOA 方法中,宿主组件的环境抽象成容器,它提供已知的服务集。从 UI 的角度来说,承载客户端 UI 组件的三个主要的容器是:

  • 基本 Web 浏览器。
  • 使用 Java™Script 和动态 HTML 增强的 Web 浏览器。
  • IBM Workplace™ Client Technology™——具有本地 IBM WebSphere® Application Server 客户机支持的 Eclipse 富客户机。

这些容器可以通过支持下列技术得以增强:Servlet、JavaServer Page (JSP) 和 JSP Tag;用于页面排序的 Struts;用于高级页面组合的 JavaServer Face (JSF);以及合并在同一页面上的多应用程序视图的 Portlet 技术。

UI 开发框架

UI 开发框架可以简化创建面对用户的复杂应用程序的过程。通常使用下列的 UI 框架来创建 UI 组件:

  • Struts,拥有最大的开发人员社区和异常工具支持,是 Apache 开放源代码项目,它早于 Java Portlet 规范 JSR 168(请参阅参考资料以获得 Struts Web 站点的链接)。Struts 是使用 servlet/JSP 范例开发基于服务器的 UI 的多页 MVC 框架。Struts 的一个特殊版本 V1.1 库支持 IBM WebSphere Portal 上的 JSR 168 Portlet。
  • JavaServer Faces 是 Java Web 应用程序的 MVC 实现,以增量方式构建于以前的技术之上。它很好地适应了 Portlet 开发,提供 Portlet 和 Servlet、声明处理、确认和事件处理。JSF 页面具有一个或多个与该页面上的 UI 控件交互的本地模型。这些控件将 UI 属性呈现给输出,而复杂的逻辑确保它们的表示是在“正确的”地方。客户端模型可以连入企业服务总线 (Enterprise Service Bus) 来发送和接收事件。
  • Java Widget Library (JWL),是一个可供门户和 Portlet 程序员使用的扩展窗口小部件集,向 JSF 添加 JavaScript 客户端处理,而且将得到 IBM Rational® Suite® DevelopmentStudio 的支持。更新客户机本地视图省去了往返服务器的过程,缩短了几个数量级的响应时间,而且极大地改善了用户体验。

门户 提供了最好的 UI 支持。在门户体系结构中,Portlet(通常是使用上面提到的某种 UI 框架开发的)是基本构件。使用这种体系结构,开发人员可以把主要精力放在他们的应用程序的独特方面,并且将生命周期、每个用户的自定义、聚合以及与其他组件的集成等公共功能委派给中间件。

下面几部分将单个服务和门户的 Portlet 组件描述成服务聚合机制。







面向服务的 UI 的 Portlet

Portlet 组件实现了标准服务接口和协议。Java Portlet 规范和用于远程 Portlet 的 Web 服务(Web Services for Remote Portlet,WSRP)标准分别定义了 Java 和 Web 服务的这个接口(请参阅参考资料以获得更多关于 WSRP 的信息)。这两个标准非常相似,以致如果存在合适的容器或者代理,为任一接口编写的 Portlet 都可互换。

Java Portlet 示例

每个 Java Portlet 都实现了该 Portlet 接口或者扩展了实现它的类。这个接口定义了 Portlet 和它的容器之间的服务约定,以及 Portlet 的生命周期:

  • 初始化 Portlet 并将其放入服务中(init 方法)
  • 处理请求(processActionrender 方法)
  • 除去服务的 Portlet(destroy 方法)

在处理请求期间,Portlet 容器调用 Portlet 的:

  • processAction 方法来通知 Portlet 用户行为。每个客户机只有一个基于用户的行为被触发。Portlet 可以发出一个重定向、改变它的 Portlet 模式或窗口状态或者更改它的状态。
  • render 方法来请求标记片段。

Portlet 还可以调用更多的服务来执行所需的功能。清单 1 示例使用 Web 服务来检索和显示特定用户的股票报价。


清单 1. 股票报价 Portlet 代码示例
												
																		public class StockQuotePortlet extends GenericPortlet {

	private ServiceManager serviceManager;

	public void init(PortletConfig config) throws PortletException {
		serviceManager = new ServiceManager();
	}

	public void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException {
		
        	response.setContentType("text/html");    

        	// invoke autogenerated wrapper to locate service
		NetXmethodsServicesStockquoteStockQuoteServiceLocator loc = 
			new NetXmethodsServicesStockquoteStockQuoteServiceLocator();
		NetXmethodsServicesStockquoteStockQuotePortType port = 
			loc.getNetXmethodsServicesStockquoteStockQuotePort();

		// loop through all stock quotes the user is interested in
		PortletPreferences prefs = request.getPreferences();
		Iterator quoteKeys = prefs.getMap().keys().iterator();
		String key;
		Float quote;
		StockBean quoteBean = new StockBean();
		while ( quoteKeys.hasNext() ) {
			key = quoteKeys.next();
	    		quote =  port.getQuote (key);
			quoteBean.add(key, quote);
		}

		request.setAttribute("StockQuoteBean", quoteBean);

		// render stock quotes using a JSP        
        PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("jsp/View.jsp");
        rd.include(request,response);

	}
}
			
												
										

这一部分演示了您可以如何使用 Java Portlet 规范来实现 UI 服务,以及您的 Portlet 可以如何调用其他 Web 服务。下一部分将展示如何使用 WSRP 将 UI 作为 Web 服务发布。

用于远程 Portlet 的 Web 服务

WSRP 是远程呈现 Portlet 的标准,使门户能够从多个源聚合内容。WSRP 将 Web 服务的集成能力扩展到面向表示的组件,并将视图层公开为跨平台、实现语言和供应商共享。可以发现内容和应用程序提供者并将其插入遵循标准的应用程序中,而不必进行任何额外的编程工作。

典型的 Web 服务使用远程表示范例,这意味着所有的视图逻辑在客户机上执行,而应用程序逻辑和数据层(控制器和模型)则驻留于服务器上。与此相反,WSRP 使用分布式范例将客户机和服务器的表示分开。


图 1. 面向数据的 Web 服务和 WSRP 面向表示的 Web 服务的比较
WSRP 比较

上图展示了这一差异。左边是典型的面向数据的 Web 服务,它提供了无格式的数据;它必须完全依赖于客户端的呈现代码来表示数据。(这意味着需要在客户机上安装和管理客户端应用程序组件。)右边是 WSRP 服务;它的分布式表示逻辑将表示任务分成:

  • 生成标记语言。
  • 将标记片段聚合成一个 Web 页面(没有显示)。
  • 通过标准客户端容器呈现标记语言。

WSRP 示例

清单 2 展示了一个通过简单对象访问协议(Simple Object Access Protocol,SOAP)从 WSRP 使用者发出的 WSRP getMarkup 请求的示例。


清单 2. 通过 SOAP 发出的 WSRP GetMarkup 请求
												
																		<?xml version="1.0" encoding="UTF-8"?>
   <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 				 
   xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
      <soapenv:Body>
         <getMarkup xmlns="urn:oasis:names:tc:wsrp:v1:types"> 
            <registrationContext>
               <registrationHandle>192.168.66.57_1096235652731_0</registrationHandle> 
            </registrationContext>
            <portletContext>
               <portletHandle>0.1</portletHandle>   
            </portletContext>   
            <runtimeContext>    
               <userAuthentication>wsrp:none</userAuthentication>    
               <portletInstanceKey>ProxyTest_row1_col1_p1</portletInstanceKey>    
               <namespacePrefix>Pluto_ProxyTest_row1_col1_p1_</namespacePrefix>   
            </runtimeContext>   
            <userContext>    
               <userContextKey>dummyUserContextKey</userContextKey>   
            </userContext>   
            <markupParams>    
               <secureClientCommunication>false</secureClientCommunication>    
               <locales>en</locales>    
               <locales>de</locales>    
               <mimeTypes>text/html</mimeTypes>    
               <mode>wsrp:view</mode>    
               <windowState>wsrp:normal</windowState>    
               <clientData>     
                  <userAgent>WSRP4J Proxy Portlet</userAgent>    
               </clientData>    
               <markupCharacterSets>UTF-8</markupCharacterSets>    
               <validNewModeswsrp:view</validNewModes>    
               <validNewModes>wsrp:help</validNewModes>    
               <validNewModes>wsrp:edit</validNewModes>    
               <validNewWindowStates>wsrp:normal</validNewWindowStates>>    
               <validNewWindowStates>wsrp:maximized</validNewWindowStates>    
               <validNewWindowStates>wsrp:minimized</validNewWindowStates>   
            </markupParams>  
         </getMarkup> 
      </soapenv:Body>
   </soapenv:Envelope>
 			
												
										

WSRP 生产者对这个请求的响应是 HTML 片段,使用者(通常是门户)可以将其聚合成一个完整的文档,例如门户页面。

不是将每个应用程序或 Portlet 部署到有意使用它的每个服务器上,而是跨网络边界共享应用程序,这具有明显的优势。WSRP 支持:

  • 更简单的管理——门户管理员可以浏览要提供的 WSRP 服务的注册中心,而不是管理可插入组件的本地部署。用户受益于及时使用随需应变的新服务和内容集成。
  • 负载分配——跨多个服务器分配负载。
  • 减少基础设施成本——应用程序可以共享承载的基础设施。例如,只分配后端银行应用程序的表示层(通过 WSRP)保护了应用程序提供者的安全计算环境,而与此同时,用户仍可以与共享的 UI 进行交互。
  • 控制内容表示——在门户重新分配内容时,内容和应用程序提供者可以极大地扩展新用户的范围。






门户:面向服务的 UI 的动态集成

门户的视图层将多个后端服务的 UI 集成为一个集中管理的 UI,这样可以统一分离的 IT 基础设施,并通过控制单一的 UI 向用户提供 IT 服务的单一视图。最初分开设计的应用程序可以连接起来构成组合应用程序,用于支持新的功能。例如,连接到协作 Portlet 的电子邮件 Portlet 可以过滤收件箱,使仅当寄件人在线并可以聊天时才显示所收到的电子邮件——这种能力是这两个原始应用程序所不具备的。

这种 portal 模型的重要意义在于改善了随需应变业务 (On Demand Business) 的敏捷性。管理员成为应用程序集成者,定义新的页面,向它们添加 Portlet,将 Portlet 连接在一起并设置权限(访问控制)——不用编程——来创建新的组合应用程序。自服务的门户使用户可以改变他们的工作环境,以适应他们独特的需求。门户体系结构解放了应用程序开发人员,使其能够全神贯注地创造新的业务价值。

将来,门户甚至能够集成组合服务,因而能够在更高的层次上聚合 UI。门户可以无缝地与来自其他门户的内容相集成,从而提供水平的、企业级的内容集成。







总结

使用门户/Portlet 体系结构,将 SOA 概念应用到用户界面,并委派公共的软件生命周期功能给 UI 容器,这改善了软件开发人员的时间价值 (time-to-value)。WSRP 标准通过 Web 服务交付 UI 组件,为内容提供者和内容使用者提供便利,从而在不用进行任何编程的情况下支持某种类型的应用程序集成。

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

网格实践: 在 SOA/Web 服务环境中监视和发现网格服务-----使用 Globus Toolkit 4 中的开放源码信息服务

本文将简要介绍 Globus Monitoring 和 Discovery Service(MDS)。本文讨论了构成 MDS 的组件,并介绍了在网格环境中其他服务通常是如何与 MDS 进行交互的。在阅读本文之后,您应该可以配置 Globus MDS 并注册服务,以及 为 MDS 配置其他信息提供者。您将学习如何组织信息并按照 MDS 的层次结构来配置多个 Index Services,从而构成网格的 Index Service。

Globus Monitoring 和 Discovery Service

Globus Monitoring 和 Discovery System(MDS)是一组 Web 服务,用来监视和发现网格中的可用资源和服务。顾名思义,人们通常会认为资源发现的过程就是发现新的资源。然而,在网格环境中,资源发现是确定哪些网格资源最适合完成某个任务的过程,要求时间最短,利用资源的效率最高。这个过程是从识别可以满足或超过当前作业需求的资源开始的。这通常是可用资源的某个子集。

接下来,我们需要通过选择最适合的资源来细化这个清单。这个选择过程需要静态和动态的信息。通常,静态信息(例如 CPU 数量、时钟速度、物理内存总量、虚拟内存以及可用磁盘空间)可以帮助确定哪些资源能够满足或超过任务的需求。在细化这个清单时,也要考虑一些动态信息。动态信息包括可用 CPU 的个数,队列中等待执行的作业个数,当前资源的利用率。现在这已经成为一个调度问题,必须考虑业务策略、优先级和服务级别协定(SLA)。

调度并不是本文的重点,因此让我们保留整个主题改天再来讨论。Globus MDS 提供了有关资源的信息,这样就可以制定智能的调度决策,从而最好且最有效地利用可用资源。MDS 也可以监视资源,在状态发生变化时通知感兴趣的团体,并根据预先定义的条件采取行动。







Index 和 Trigger Service

我们对 MDS 所搜集到的有关资源的状态进行监视。搜集这些信息的 MDS 服务称为 Index Service。MDS Index Service 的工作方式与注册表非常相似。它搜集信息,然后将其作为资源属性发布。它通过一个 Web 服务接口将所搜集的信息提供给客户机。客户机可以向 MDS 查询信息,或者订阅所感兴趣的资源属性,即表明如果这些属性的值发生了变化,它们非常乐于被及时通知。这些信息代表了资源属性的配置和状态。Globus MDS 可以监视资源,并跟踪所选择的资源属性。它可以通知订阅者属性值发生了变化。

这种功能是由另外一个名为 Trigger Service 的 MDS 服务提供的。它与 MDS Index Service 类似,都要从资源中搜集数据,但是它同时还要对所搜集的数据进行监视,这样就可以在数据到达某个极限值时执行某些预定的操作。Trigger Service 的配置就是订阅某些属性,并指定当某个属性值达到某个预定的极限时应该采取什么操作。要采取的操作可以非常复杂,例如当利用率太高时提供更多资源;也可以非常简单,例如通知系统管理员某个文件系统已经满了。MDS Trigger Service 通过 Web 服务提供此功能。客户机使用这个 Web 服务来注册触发器事件。为了进行注册,客户机要提供程序的名字、一个 XPath 查询表达式以及一个值。当 XPath 查询所返回的值等于注册时所提供的值时,就运行这个程序。MDS Trigger Service 通过对所搜集到的信息和在 MDS Trigger Service 注册和配置文件中所指定的条件进行比较,来提供这种功能。


位置 1. Trigger Service 注册和配置文件的位置
												
																		
$GLOBUS_LOCATION/etc/globus_wsrf_mds_trigger/trigger_registration_aggregation.xml

												
										

这个配置文件使用 XPath 查询表达式的格式定义了一些规则。每个规则都有一个当满足该条规则时所要执行的操作,以及该操作重复的频率。下面这个例子实现了触发器规则、相关操作以及频率的语法,这些都是在前面的触发器注册和配置文件中指定的。


清单 1. Trigger Service 注册的例子
												
																		
       <trigger:TriggerRuleType>
          <trigger:matchingRule>//*[local-name()='GLUECE']</trigger:matchingRule>
          <trigger:actionScript>glue-trigger-action.sh</trigger:actionScript>
          <trigger:minimumFiringInterval>600</trigger:minimumFiringInterval>
       </trigger:TriggerRuleType>

												
										







MDS Aggregation Framework

MDS Index 和 Trigger Service 都是在 MDS Aggregation Framework 之上构建的。MDS Aggregation Framework 用来构造搜集和聚集数据的高层服务。这些聚集器服务将从各种资源搜集来的信息汇集到一个集中的位置。这个概念的范围很广,从在某个容器中运行的所有服务的集中注册表,到一个网格范围的 Index Service,这可以通过配置 Index Service 与其他 Index Service 一起来存放内容。Index Service 可以按照一种层次化的方式进行配置,上层可以从底层的 Index Service 中提取信息。上层 Index Service 可以当作是这个层次中的上游资源,底层 Index Service 可以当作是下游资源。Index Service 在这个层次中的位置是在层次配置文件中使用上游和下游服务这两个术语进行定义的。


位置 2. MDS 层次文件的位置
												
																		

$GLOBUS_LOCATION/etc/globus_wsrf_mds_index/hierarchy.xml 

												
										

这个层次文件指定了上游和下游 Index Service 的 URL。下面这个样例声明中包括了主机名、端口和默认的 Index Service 的标识。清单 2 显示了 Globus Toolkit 4 测试环境中上游和下游服务的声明。


清单 2. 上游和下游服务声明的例子
												
																		

     <upstream>https://gt4-primary:8443/wsrf/
     services/DefaultIndexService</upstream>

     ...

     <downstream>https://gt4-secondary:8443/wsrf/
     services/DefaultIndexService</downstream>

												
										







MDS 资源属性

正如前面介绍的,用户可以向 Globus MDS 查询资源的属性。这些资源属性代表了资源的配置和状态。我们可以为永久资源和临时资源维护一些属性。Globus MDS 中的信息通过为资源数据关联一个超时时间来保证其反映最新情况。这个值被称为生命周期。MDS Index Service 中保存的所有服务都有一个相关的生命周期。如果在这个生命周期指定的时间内没有更新,数据就过期了。这种方法可以通过只在相关的资源属性进行更新时维护这些资源的配置和状态,从而对临时资源进行处理。当资源不再可用时,资源属性就不会更新了,这些信息就会超时并被删除。







MDS 资源特性

Globus MDS Index Service 信息是作为一组 Web Services Resource Framework(WSRF)资源属性进行维护的。客户机可以使用 WSRF get-property 和 WS-Notification subscribe 操作来查询信息或在信息发生变化时收到通知。这些信息也可以使用命令行工具 wsrf-get-propertywsrf-query 进行查询。Globus MDS Index Service 通过用 XML 格式提供所请求的信息来对查询进行响应。下面这个例子执行了一个通用的 DefaultIndexService 查询。–a 选项指定可以进行匿名验证,–s 选项指定了服务的 URL,–z 选项定义了验证类型可以是自己、主机或 none。请参阅 清单 3







XPath 查询

查询可能会产生非常大的 XML 文档。XPath 可以用来帮助定位 XML 中的不同部分。下面让我们来看几个例子,以此展示怎样扩充简单查询来搜集更详细的信息。下面这个例子可以通过统计那些属性匹配 FreeCPU 状态的 ComputingElements,来查询空闲 CPU 的个数。


清单 4. 一个查询空闲 CPU 的 wsrf 查询
												
																		
[globust@gt4-test sbin]$ wsrf-query -a -z none -s 
https://127.0.0.1:8443/wsrf/services/DefaultIndexService
 
"count(//*[local-name()='GLUECE']/glue:
ComputingElement/ glue:State/@glue:FreeCPUs)"

2

												
										

利用前面的例子,下面这个查询展示了一个布尔检查,看是否有指定个数的 CPU 可用。请参阅 清单 5







监视服务

我们已经讨论了上面这些物理资源的概念,但是 MDS 还要监视服务的配置和状态信息。MDS Index Service 会搜集有关容器上运行的其他服务的信息。服务指定了在 Aggregation Service 注册信息时,要将哪些信息保存在 MDS 中。我们稍后会讨论 Aggregation Service,但是首先介绍一下服务注册这个主题。

服务可以使用 mds-servicegroup-add 命令进行注册。每个注册后的服务都有一个类似于前面介绍过的生命周期属性的生命周期。如果某个服务的注册项在一段指定的生命周期中没有更新,就会过期。更新生命周期的一种方法是在后台运行 mds-servicegroup-add 命令,这样它就可以持续在 MDS 中更新服务注册项并刷新服务的生命周期了。

MDS Aggregation Service 从所有的已注册服务中搜集信息,并通过一个 Web 服务接口将这些服务信息提供给客户机。Globus Toolkit 发行版本中提供了一个简单的例子来展示如何在 MDS Aggregation Service 中注册服务。这个例子使用了下面这个位置上的服务注册定义文件。


位置 3. MDS 聚集注册文件的位置
												
																		
$GLOBUS_LOCATION/etc/globus_wsrf_mds_
aggregator/example-aggregator-registration.xml

												
										

这个样例聚集文件定义了服务的注册表。每个注册项都定义了一个网格资源、该资源应该注册的服务组以及服务配置参数。这个文件可以与 mds-servicegroup-add 命令一起维护网格资源与 Index Service 之间的注册。这个文件定义了 Index Service 的位置,它被称为默认的 Service Group End Point Reference。


清单 6. Index Service URL 被定义为默认的 Service Group End Point Reference
												
																		
<defaultServiceGroupEPR>
   <wsa:Address>https://gt4-test.tacc.utexas.edu:8443/
   wsrf/services/DefaultIndexService</wsa:Address>
</defaultServiceGroupEPR>

												
										

example-aggregator-registration 文件中包含了 GRAM 和 RFT 服务的样例注册项。在 ServiceGroupRegistrationParameter 块中定义的每个资源都要在 Index Service 中进行注册。 清单 7 显示了一个 GRAM 和 RFT Service 注册项的例子。

MDS Aggregation Service 也可以对外部信息源的信息进行聚合。这些信息源可以代表本地服务可能需要的远程资源。本地服务可以查询 MDS Index Service 来定位远程资源,并确定这些资源的状态。举例来说,下面这个例子就展示了将 Hawkeye 在默认的服务组中注册为一个信息源。Hawkeye 是一个外部信息源的例子。它使用 Condor 技术(例如 ClassAds)来搜集和存储有关 Condor 池中的资源的信息。清单 8 显示了如何注册 Hawkeye,这样就可以通过 Index Service 来使用有关 Condor 的信息了。


清单 8. 聚集服务组的例子
												
																		
<ServiceGroupRegistrationParameters
   xmlns="http://mds.globus.org/servicegroup/client" >
    <RegistrantEPR	`
      xmlns:agg="http://mds.globus.org/aggregator/types"
      xmlns:gram="http://www.globus.org/namespaces/2004/10/gram/job"
      xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
      <wsa:Address>
          https://gt4-test:8443/wsrf/services/mds/test/subsource/IndexServiceEntry
      </wsa:Address>
      <wsa:ReferenceProperties>
         <gram:ResourceID>Hawkeye</gram:ResourceID>
      </wsa:ReferenceProperties>
   </RegistrantEPR>
   <RefreshIntervalSecs>600</RefreshIntervalSecs>
   <Content xsi:type="agg:AggregatorContent"
      xmlns:agg="http://mds.globus.org/aggregator/types">
      <agg:AggregatorConfig xsi:type="agg:AggregatorConfig">
         <agg:ExecutionPollType>
            <agg:PollIntervalMillis>60000</agg:PollIntervalMillis>
            <agg:ProbeName>globus-mds-cluster-hawkeye</agg:ProbeName>
         </agg:ExecutionPollType>
      </agg:AggregatorConfig>
      <agg:AggregatorData/>
   </Content>
</ServiceGroupRegistrationParameters> 

												
										

当服务进行注册时,它们可以提供搜集服务信息的程序名。这个程序称为执行聚集器,在清单 8 中是使用 ProbeName 的形式指定的。MDS Aggregator Service 可以查询资源属性信息,也可以订阅资源属性信息,这样就可以推动后续的更新了。要注册服务,可以使用位置 3 所给出的 example-aggregator-registration 文件作为 mds-servicegroup-add 命令的参数。下面这个例子展示了使用 mds-servicegroup-add 命令来注册默认的 example-aggregator-registration.xml 文件中所定义的服务。–s 参数告诉 MDS 这些服务应该要进行注册。请参阅 清单 9

可以使用 wsrf-query 命令验证服务是否成功注册。下面这个例子显示了一个 ContainerRegistryService 查询,用来获得容器中正在运行的服务的地址。要在另外一个环境中使用这个查询,请替换 URL 的主机名部分。


清单 10. 使用 wsrf-query 命令查询注册表地址的例子
												
																		
wsrf-query -s https://gt4-test.tacc.utexas.edu:8443/wsrf/
services/ContainerRegistryService
 "/*/*/*/*[local-name()='Address']"

												
										







MDS 聚集类型

我们已经介绍过 Web 服务会发布资源属性。一个服务应该注册的最小资源属性集包括服务名、服务的版本号以及这个服务是何时启动的。有些服务(例如 GRAM 或 RFT)会发布其他信息或更详细的信息。MDS 中的信息是使用 3 个聚集器源(Aggregator Source)进行搜集的。这 3 个聚集源是 Query Aggregator、Subscription Aggregator 和 Execution Aggregator。

前面用来展示服务组注册的那个例子就是一个 Execution Aggregator。Query Aggregation Source 会对注册的服务进行挑选来产生信息。Subscription Aggregation Source 订阅服务数据,这样在服务数据值发生变化时,就可以接收到通知。Execution Aggregation Source 运行一个程序来搜集信息。发布资源属性或用来搜集服务数据的程序有时称为信息提供者(Informational Providers)。GRAM 就是一个信息提供者,因为它会发布有关网格资源的 CPU 和内存信息,以及与作业队列和所提交的作业有关的调度器信息。类似地,可靠文件传输服务(RFT)也是一个信息提供者,它发布的是有关传输器和服务器的状态信息。除了这些信息提供者(它们都是 Globus 发行版中的一部分)之外,MDS 还可以与其他外部信息提供者进行集成,例如 Ganglia 和 Hawkeye。

Ganglia 是一个分布式的监视系统,主要用来监视高性能系统,例如集群。Hawkeye 是一个监视系统,它使用 Condor 工具和 ClassAd 机制来收集有关分布式资源的信息。Ganglia 和 Hawkeye 使用 GLUE 模式的 CML 映射来搜集资源信息,并将这些信息发送到一个 GRAM 服务,这些信息将在这个服务中作为资源属性发布。Ganglia 信息包括主机属性,例如主机名、处理器、内存、操作系统以及文件系统,还有负载信息。如果在 gluerp XML 文件中定义并配置了适当的信息提供者,MDS 就可以汇集 Hawkeye 或 Ganglia 的信息。


位置 4. GLUE 资源提供者的位置
												
																		
$GLOBUS_LOCATION/etc/globus_wsrf_mds_
aggregator/example-aggregator-registration.xml

												
										

Globus 默认的配置说明没有信息提供者。要指定 Hawkeye 或 Ganglia 作为信息提供者,请修改 gluerp.xml 文件中的适当项,这个文件位于 Globus 安装目录中的 etc/globus_wsrf_mds/usefulrp 目录中。下面这个例子展示了指定 Hawkeye 作为信息提供者的正确定义。后面的例子将展示如何配置 Ganglia 作为信息提供者。


清单 11. 信息提供者注册项
												
																		
<config xmlns="http://mds.globus.org/2004/10/gluerp-config">
   <defaultProvider>shell /usr/local/globus/globus-4.0.0/
   libexec/globus-mds-cluster-hawkeye </defaultProvider>
</config>

   ...

<config xmlns="http://mds.globus.org/2004/10/gluerp-config">
   <defaultProvider>java org.globus.mds.usefulrp.glue.
   GangliaElementProducer</defaultProvider>
</config>

												
										







webMDS

我们在前面已经看到可以使用 wsrf-query 命令来查询 MDS 信息。实际上,MDS 信息也可以使用 webMDS 进行查看。webMDS 是一个用来查看 MDS 中所包含的资源属性信息的前端。webMDS 是一个 servlet,它可以查询 Globus MDS Index Service,并使用 XSLT 转换对数据进行格式化,从而可以很好地在 Web 浏览器中显示。

Web 管理员可以使用 HTML 表单选项定制 webMDS。他们可以配置不同的插件来搜集数据,并使用 XSLT 转换对这些数据进行格式化,从而创建自己的定制视图。webMDS 可以配置为从 MDS 中的各种源搜集信息,并使用 XSL 转换对这些信息进行过滤。如果 Globus Toolkit 是使用默认配置安装的,那么 webMDS 就可以查询 MDS Index Service,而不用修改任何配置。我们测试环境中使用的 webMDS URL 如清单 12 所示。要在另外的环境中使用 webMDS,请使用您自己的主机名替换其主机名部分,如果您不是在默认端口上运行容器的,还需要修改端口号。


清单 12. webMDS URL
												
																		
http://gt4-test.tacc.utexas.edu:9080/webmds

												
										

可以通过编辑下面的 indexinfo 文件并修改默认的 URL 来改变 webMDS URL :


位置 5. MDS 聚集注册文件的位置
												
																		
$GLOBUS_LOCATION/lib/webmds/conf/indexinfo

												
										

要部署 webMDS,首先为 Globus (GLOBUS_LOCATION) 和 Tomcat (CATALINA_HOME) 设置环境变量,然后使用下面的命令为 Tomcat 创建一个 context 文件:


清单 13. 创建 webMDS context 文件
												
																		
$GLOBUS_LOCATION/lib/webmds/bin/webmds-create-contex-file
  \ $CATALINA_HOME/conf/Catalina/localhost

												
										

在成功运行这个命令创建 context 文件之后,请重新启动 Tomcat,以便使用新的配置信息。重新启动 Tomcat 可以使用下面的命令:


清单 14. 重启 Tomcat 容器
												
																		
$CATALINA_HOME/bin/shutdown.sh
…
$CATALINA_HOME/bin/startup.sh

												
										

重启 Tomcat 容器之后,可以在浏览器的地址栏中键入 webMDS 的 URL(请参阅清单 12)来访问 webMDS。这个 URL 中需要替换上您安装使用的主机名和端口号。注意,这是 Tomcat 中运行 webMDS 的 URL,而不是在 Globus 容器中运行的 MDS 服务的 URL。

这个样例表单是由 Globus 发行版提供的,用来展示 webMDS 的功能。也可以使用模板来创建新的定制请求。

通过 webMDS 来查询 Index Service 可以显示在 Index Service 中注册的资源。每个服务都提供了一种资源类型、惟一标识符和一个链接(指向更详细的信息)。选择资源项可以产生有关资源的详细信息。我们已经介绍过 GRAM 和 RFT 服务都在 Index Service 中进行了注册。图 1 是一个显示与 RFT 服务有关的详细信息的例子。


图 1. RFT 服务的 webMDS 信息
RFT 服务的 webMDS 信息

如果 GRAM 配置用来与资源管理器一起使用,例如 LSF、PBS 或 Condor,那么每个资源都会存在这样一个注册项。

图 2 和图 3 显示了与 LSF 服务有关的详细信息。


图 2. globus-mds-LSF 例子 1
globus-mds-LSF

图 3. globus-mds-LSF 例子 2
LSF 服务组

图 4 显示了与 Condor 服务有关的详细信息。


图 4. globus-mds-condor_cluster 例子
Condor 服务组

webMDS 是 MDS Index Service 的一个简单易用的接口。我们在前面已经展示了 mds-servicegroup-add 命令可以用来在 MDS 中注册服务,聚集源可以配置为对来自服务和外部信息提供者的信息进行汇集。这些信息提供者运行了一个程序来搜集信息,它们都是 Execution Aggregators。这很容易展示,可以手工运行信息提供者,并验证这些信息和格式与通过 webMDS 所提供的信息和格式完全相同。下面这个例子显示了 Hawkeye 信息提供者的情况,这是由清单 8 中下面这一行定义的:

												
														<agg:ProbeName>globus-mds-cluster-hawkeye</agg:ProbeName>

												
										

请参见 清单 15







结束语

我们首先概要介绍了 Globus MDS,然后了解了某些底层服务的详细知识。Index Service 是一个注册表,负责搜集信息并以资源属性的形式来发布这些信息。Trigger Service 使客户机可以订阅资源属性,并在数据达到某个极限值时执行预定义的操作。这些服务都是构建在 Aggregation Service 之上的,后者也可以对来自外部信息源的信息进行聚集。这些信息可以汇集到一个集成的注册表中,称为网格 Index Service。Index Service 以编程方式向客户机提供了资源属性信息,这可以通过 Web 服务、命令行接口或浏览器来接收。

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

为面向服务的解决方案建模

本文来自于 Rational Edge:IBM Rational Unified Process Update for Service Oriented Architecture(RUP Update for SOA)与 UML Profile for Software Services 的 Rational Software Architect 实现的结合提供了建模方法,以及一组用于面向服务体系结构模型解决方案的体系结构和设计的最佳实践。本文描述了背景、范围和此新功能背后的一些概念。

插图 三年前,我们这些处于 Rational Software Corporation 前沿的一组人坐下来撰写了一篇有关利用面向服务的体系结构(service-oriented architecture,SOA)式样1来开发解决方案问题的文章,并且从那以后发生了许多事。我们所面临的一个问题是 Rational Software 有一组建模工具,但没有 IDE 来实际地开发我们所建模的服务实现。随着 IBM 对 Rational 的收购,我们现在有了一个世界级的 WebSphere Studio Application Developer(现在是 Rational Application Developer,或 RAD)形式的 IDE。我们还面临着一个问题,许多关于 SOA 的思想都不成熟,并且许多是被错误驱使的 —— 一个我们在文章中考虑的问题。既然支持 SOA 的 IBM 平台已经相当地成熟,并且我们的开发工具已经增加了按照灵活快捷的方式开发服务的功能,我们决定再次访问我们在前面文章中概括的服务设计的概念。

此讨论的结果是一个新的理解:我们的价值不是在表现 WSDL(Web 服务描述语言)和 XML 的所有三角地的模型开发,而是允许设计人员和架构师用恰当的功能指定恰当的服务并实现 SOA 式样的潜在益处。 此理解将我们引向一些长远的讨论,这些讨论是关于 1) 用来表现服务模型的恰当抽象级别,和 2) SOA 式样的开发影响 Rational Unified Process®,或 RUP® 的方式。

本文的前三分之一介绍了我们为变更所设置的范围,包括我们所关注的需求。接下来我将描述一些关键的主题,我们将这些主题用作对 RUP 的变更框架,及用于支持面向服务的解决方案开发的 Rational Software Architect(RSA)补充。最后,我将描述一些在我们的思想中使用的情境,这些情境随时间得到了改进,但还需要一些关键客户的验证。

设置恰当的范围

我们决定不仅开发一个新的用于 RSA 的建模概要文件,还要开发添加到 RUP 中的指导,为帮助实践者在预想和开发面向服务的解决方案中实际地使用工具。

然而,众所周知,对于任何项目最关键的方面之一是设置恰当的范围:太小,您就会做出对任何人没有实际意义的东西(除了可能能够拿出您自己的要获得利益的目的),太大,就很可能要煮沸整个海洋。所以我们建立了以下标准:

  • 我们开发的模型必须要处于当前实现技术和标准之上的抽象级别上(WS-* 规范,就是各种 Web 服务规范),然而,还要将 SOA 的概念作为头等的要素。

  • 结果的模型必须是可扩展的,可以考虑到相关的额外规范,如安全性、服务质量,可管理性,等等。

  • 模型必须在 IBM Rational Software Modeler(RSM)和 IBM Rational Software Architect(RSA)中实现,最初作为一个 UML 概要文件。

  • 指导不得不向基础 RUP 添加具体的 SOA 概念。然而,我们想要在现有的 RUP 中利用尽可能多的东西,因此,为了使更新很容易地添加到现有的 RUP 配置中,我们最初选择不改变任何存在的东西。

  • 我们的工作应该考虑在提供 SOA 指导中 IBM 已经完成的工作,如 IBM Global Services SOMA 技术。2

因此我们定义了一组三个可交付使用的标准,每一个都可以从 IBM developerWorks 中得到:

  • 描述 UML Profile for Software Services 的文档,3它依照的是 OMG 概要文件文档的式样。

  • 实现 UML Profile for Software Services 的 RSM 或 RSA 插件,4它使模型构建于工具之中并符合上面的概要文件。

  • 包含了所有关于 SOA 体系结构5和设计主题指导的 RUP 插件,它提供了关于依照上面的概要文件开发服务设计模型的具体指导。

幸亏 RSM 和 RSA 工具具有可扩展机制,我们才能够不仅交付 UML Profile for Software Services,还交付一个模板模型(当您选择 File -> New -> UML Model 时可用)和两个添加到 Sample Gallery 中的示例。

这是我们考虑的一个合理的标准集合并可以交付。所以让我们看看在 2005 年 5 月 IBM developerWorks 中实际交付的内容。







关键概念和主题

首先,什么是 SOA?流行着许多定义,但让我们以一个软件工程师的角度去看,简单地说 SOA 是一个“体系结构式样”的实例。这又引出一个问题,什么是体系结构式样?这里有一个来自 Roy Thomas Fielding 的很好的定义:

体系结构式样等同于限制体系结构要素的作用或特性及任何体系结构中符合该式样的那些要素之间的容许关系的体系结构约束。6

举个例子,一个已编制的体系结构式样是管道和过滤器样式,它包含了将管道作为连接器来关联过滤器的独立的要素。在管道连接的两个过滤器之间存在着数据类型必须遵照的具体的约束,且存在着一些令式样适应于某些环境的特征。

知道了这些,我们可以开始列举 SOA 的体系结构要素,以及具体到其式样的关系和约束。有了这个有用的体系结构式样的定义,Fielding 还提供了一个非常及时的建议:

设计这个强意词是普遍发生的。至少软件行业中的某些此种行为还缺乏对为什么已知的体系结构约束集合是有用的的理解。换句话说,在选择复用那些体系结构时,好的软件体系结构背后的原因对设计人员不是显然的。7

我们希望通过提供 RUP 中的具体附加内容集的简明及时的指导来缓和此精确的行为。此指导描述了体系结构的式样、要素和关系,以及在整个开发生命周期中他们是如何被识别、指定和管理的。同事还要注意,通常体系结构的目标,特别是体系结构建模,提供了一个适当的抽象级别,在此级别上,可以容易地识别体系结构的要素,并且在不隐藏那些应该添加到针对实现更低层细化级别的细节的情况下,对要素进行控制。

在下面几个部分中,我们将讨论针对 SOA 的 RUP 更新中的一些关键主题 —— 特别是,要素、关系和每个主题引入的约束。

服务的识别和说明

我们的标准规定,关键的 SOA 概念必须作为头等要素通过模型表现出来,因此这些关键的概念是什么?如您所预想的,其中一个概念就是服务本身,然而,与其作为模型建立的中心,还不如实际地成为次要的要素(不是重要的,但作为模型的要素,因为它不能独立存在)。要构建一个表现 WSDL 所定义服务的服务模型,我们必须首先开发服务规范以及服务供应商

服务规范有三个规范要素,所有都同样重要,虽然在某种情况下,根据服务的建模类型可对它们进行选择:

  • 结构规范。它可以用标准的 UML 或 Java 接口考虑。其定义了可以调用的操作和由这些操作销毁或创造出的消息。

  • 行为规范。它表示出服务客户和所指定服务之间的任意预期的有意义的协议或会话。例如,服务也许要求您在调用另一个操作之前先登录,这称为伪对话服务。服务也许还要求客户实现特殊的接口,以便接口可以被回调,且协议可以展示这点。

  • 策略规范。它表示服务的策略主张和约束。策略主张可能包括安全性、可管理性等等。

那么,例如,如果我们设想一个订单管理服务,我们也许期望看到列出“下订单”、“取消订单”和“更新订单”作为可用操作的结构规范。此订购服务的行为规范可能会说明,您如何不能更新或取消没有订购的订单,或者在您取消订单之后就不能再对其更新。最后,策略规范可能要求加密订单的某些要素,指示要使用的加密技术、要使用的证书等等。

我们在 RUP 中已经交付的指导的一个方面是一组技术(新的行为识别服务中进行了描述),用来从业务过程模型、用例或现有的各种清单资产中确定服务。这种行为和这些技术集允许架构师和设计人员制造出候选服务模型,这些模型是经常用于描述用来实现过程或需求集的“理想化”服务的服务规范。

我们介绍术语“候选服务”,因为许多这些服务经常不得不被重构来 1) 符合现有服务,2) 适应现有功能体系结构的框架,或者 3) 被分开以考虑更细致或并行的开发。

管理服务组合

SOA 式样解决方案的开发的一个主要优点是在开发一个应用程序时(收集需求、设计并实现解决方案,且管理项目),不用将应用程序作为一个固定的边界考虑。在 SOA 中,我们看到的应用程序是一个动态的实体,一个满足特殊业务需求集的服务配置。要达到这种状态,我们显然需要在企业中设计、实现并管理作为可用功能组合的服务集。

该需求就是为什么我们指定前面提到的新的识别服务行为的原因。我们不仅是在识别候选服务时考虑组合,我们还由服务的原始形式进行重构以适应组合中服务的形式。该级别的复用不仅应该得到设计工具的支持,不仅应该得到关于服务组合的信息存储库的支持,还应该 —— 最重要的 —— 得到以恰当的方式开发恰当的服务时指导参与者的过程支持。

这确实导致了一个特别的问题,在传统情况下,我们关注软件开发生命周期,视其为一个由项目限制时间的过程,项目受到解决方案的某些离散部分的开发时间的限制。就服务组合本身而言(关于已安装的服务的元数据和考虑复用的设计模型的组合),我们看到这样一个生命周期,它横切了使用它并对它做出贡献的单个项目,如图 1 所示。

图 1:服务投资组合生命周期

图 1:服务组合生命周期

图 1 所示的服务组合管理过程是一个不断进展的活动。注意单个项目与服务组合交互的方式,在项目的细化阶段从单个的项目中提取需要组合的服务,在项目的构造阶段组合的服务被实现。

划分面向服务的解决方案

不管多大规模的模型(或实际上是要素的任意集合)都存在的一个问题就是如何管理模型,如何对要素分类,以及如何以任何检查模型的不同涉众都可以理解的方式来组织要素。

服务模型的此种结构在服务的识别和服务的管理过程中变得重要起来。让我们暂时考虑 UML 1.x 中的模型管理 —— 包 —— 的典型方法。关于包的问题是它们通过所有权或聚合来管理模型要素,换句话说,一旦将一个要素放入单个的包中,不同包中的要素可以对其访问但不能将其“放置”在一个以上的包中。此刻,对于我们这些具有程序设计语言背景的人来说,这似乎不是主要问题,它反映出包、模块或命名空间在语言中工作的方式。

然而,我们真正需要表示的是模型的视图,因为对业务所有者有用的结构集合不同于软件架构师、设计人员、开发人员、操作人员等所需要的集合。出于该原因,我们推荐不要将包作为管理模型视图的主要机制(不是说包中不出现服务,只是说包应该用于模型的更平凡结构)。取而代之,我们指望 UML 2.0 规范的复合结构概念,其提供了表示使用“部件”和“连接器”的分类器的内部结构功能。

我们利用这些技术划分所管理的服务,换句话说,根据逻辑分类方案进行组织,不需要让服务所属于任何一个分区。例如,我们可能有两个不同的组合视图:一个表示不同的业务线,另一个表示提供服务的应用程序“类型”,如图 2 所以。

图 2:根据逻辑分类方案利用分区进行组织,不需要让服务所属于任何一个分区

图 2:根据逻辑分类方案利用分区进行组织,不需要让服务所属于任何一个分区

注意,相同的服务(较小的方框)出现在一个以上的分区中(较大的方框),顶部的三个分区表示业务线,且底部的三个表示应用程序类型。从此处我们可以看到,虽然业务的供应链拥有并管理着 Shipping、Validation,和 Warehouse 服务,但我们可以看到 Shipping 服务由 ERP 包提供而 Warehouse 和 Validation 服务是定制开发的。

该技术不仅在管理已开发的服务集方面体现价值,还在服务的识别过程中体现价值。分区可以用于表示服务分组,并作为服务规范进行开发,可以将服务放置于不同的分区中以可视化关系和它们之间的依赖。







RUP 更新

对 SOA 的 RUP 更新已经在许多(和谐的)地方得到扩展,以提供关于体系结构开发和面向服务解决方案的设计模型的具体指导。但 RUP 的许多领域仍旧不受到该更新的影响。例如,我们在早期决定的更新的开发,尽管一些行业作家已经引入了支持 SOA 的新开发角色,但我们相信当前 RUP 的Software ArchitectDesigner 角色对于我们所需要的更新是足够的。

新的和更新的工作流

在更新 RUP 以引入对于 SOA 解决方案构建的指导的过程中,我们只添加了以下两个新活动:

  • 识别服务。由 Analysis & Design Refine the Architecture 工作流中的 Software Architect执行。

  • 服务设计。由 Analysis & Design Design Services 工作流中的 Designer 执行。

识别服务活动是软件架构师在概括解决方案的体系结构时所执行的一个活动,活动的输出是服务模型。该服务模型中包含一组已识别的,已经是候选的服务,这些服务要作为服务设计活动的一部分由设计人员进一步细化。

新的和更新的工件

更新将整个服务模型(表示 UML Profile for Software Services)和其附属的要素引入到 RUP 中。模型表示面向服务解决方案的体系结构抽象,该抽象使软件架构师和设计人员在这样一种环境下开发模型,在这种环境下,服务的概念和对 SOA 的具体关注是头等的模型要素。模型直接表示任何实现技术,如 WSDL。

图 3:UML Profile for Software Services

图 3:UML Profile for Software Services

新的和更新的指导方针

除了在服务模型中描述工件的具体内容,更新还包括与上面描述的主题相关的概念以及在开发 SOA 模型时反映对重要性所关注的额外的指导方针。这些关注包括:

  • 消息设计和消息附件。设计消息,管理可复用的消息目录和消息方案的一致性。

  • 服务数据封装。围绕服务中数据管理的服务设计特性和数据方案与服务边界之间的关系。

  • 服务仲裁。有关一般作为 SOA 式样一部分(特别是 Enterprise Service Bus,或 ESB 视野)的仲裁组件的概念的具体指导。

  • 状态管理。对有状态和无状态服务的优点的讨论,包括对于规范的技术和管理资源状态的服务设计。

我们还提供了指导方针 Going from Services to Service Components(从服务到服务组件),其论证了从服务设计模型到传统的设计或实现模型的一种可能的变换。

更新还包含两个报告描述,描述创建服务模型的 RSA 工具指导者,和表现服务模型开发的相当完整的实例。







RSM 或 RSA 插件

IBM Rational Software Modeler 和 IBM Rational Software Architect 的新插件(今后称为 RSM 或 RSA 插件)提供了 UML Profile for Software Services,一个您可以使用的模板模型,和一对论证概要文件使用的示例模型。该插件可以在 IBM developerWorks 下载,并可以利用标准的软件更新机制将其添加到工具中(注意下载的压缩文件表示一个存档更新站点)。

在 RSM 或 RSA 中,在软件服务的插件安装完之后可以很容易地创建新的服务模型。以下的步骤是必要的(注意是在 Modeling Perspective 中):

  1. 如果在您的工作区中已经有了一个 UML 建模工程,您可以将服务模型添加到该工程中或创建新工程(参见步骤 2)。

    • 右键单击工程并选择 New -> UML Model 或者在 File 菜单中选择 New -> UML Model。

    • 当您看到 New UML Model 向导时,如图 4,转到步骤 3。
  2. 要创建新的 UML 建模工程,到 File 菜单中并选择 New -> Project,UML Project 处在 Modeling 目录下面。

    • 在结果向导中,给出工程的名称并选择 Next。
  3. 在 New UML Model 向导中,如图 4 所示,确保正确设置了目标文件夹,从模板列表中选择 Service Design Model,并给模型命名。
图 4:New UML model 向导

图 4:New UML model 向导

这将创建并打开带有 UML Profile for Software Services 的 UML 模型和一个模板结构,您可能由该模板结构开始为 SOA 解决方案建模。模型还包含一组可以在创建一些复合要素时有用的可复用模型要素,至少使用这些要素要比手动创建更简单。







三个情境

以下的部分概述了我们从与客户的讨论(不论客户认为面向服务的解决方案的开发如何适应他们的软件开发生命周期)中总结出的三个情境。我们先认明三个开发服务的方法,而它们当然不是不相容的(真实的工程使用技术的组合),它们在阐明不同方法和思想方面是有用的。

在任何可能的地方,我将把在这些情境中描述的任务与 RUP 中定义的结合起来。

1. 以消息为中心的设计

在消息为中心的设计中,焦点在服务领域中。例如领域工程或面向对象分析和设计(Object-Oriented Analysis and Design,OOAD)的技术提供了许多对抽象领域模型开发的洞察,并且这些技术通常生成对应消息方案的高度可复用模型。服务设计常常是次要的活动,尽管有时候并行地完成。例如,在电子数据交换(Electronic Data Interchange,EDI)中,不存在真正的服务接口概念,因为 EDI 系统通常有一个单个的全球的消息收件箱和发件箱。

该方法的一个实例可能是在传统的B2B 环境中,以 EDI 标准化作为代表。在此种情况下,主要的设计活动涉及开发某些行业或其他范围内取得一致的消息方案,这被认为是表示一类消息的方案 —— 例如,EDI8Purchase Order、ACORD9Claim Inquiry,或者 SWIFT10Credit Transfer。

在许多现代标准活动中,如 SWIFT 或 RosettaNet,11经常存在一个用于标准的设计过程,包含了一个混合的以消息为中心并以服务为中心的方法,在该方法中使用了如用例分析的技术。

情境

在此实例中,客户是一个大的保险供应商,开发新的应用程序以支持其中一条业务线。在该公司中业务和 IT 支持之间的结合相当的好,且严密关注通过 IT 传递到业务的价值。

此情境中的项目扩展了两个索赔处理系统,以便两个系统可以提供将要启动策略集成并使公司收回一个系统并将所有索赔处理系统移到一个单个的系统中的面向服务的接口。

业务人员希望服务能够支持一些现有的业务过程,但他们清楚地知道这些过程随时变化,所以将服务与过程结合是不切实际的。作为回应,该业务领域的软件架构师相信更加适合的方法可能会集中于过程中的业务工件,主要是索赔本身。除了这些,他们已经在 IBM IAA 中投了资,12这为工件提供了定义良好的且标准的模型,如索赔。

在这点上,对于主要工件的实际数据模型已经由 IAA 指定,所以主要的工作是理解在当前系统中使用这些工件的方式及围绕着不同的实现如何开发新的外观。

活动

业务分析人员开始编制需求,还利用业务过程模型来描述系统的功能需求。非功能需求在需求数据库中进行描述,依附于业务过程模型中的任务或项。过程模型是为两个当前系统和两者的交集开发的。

软件架构师拿到了这些模型和需求并与业务分析人员一起开发集中于两个系统间一般工件的流程的更具体的过程。软件架构师还与业务分析人员一起理解当前系统的数据需求及它们到 IAA 数据模型的关系。

数据架构师与软件架构师一起描绘出针对新的过程中工件的逻辑和物理表示的方案。

软件架构师开发了一个将过程活动划分成一组服务操作的候选服务模型。该模型还包括每个服务的消息需求及这些消息到下面的数据模型的关联。

软件架构师与集成专家一起(不是通常的 RUP 角色,但对应该角色的描述是为 RUP 设计的)定义从候选模型到当前实现所需的映射(在它们存在的地方)。这些映射将在所选的中间件中实现,但不应该像引入主要性能问题那样麻烦。

2. 以服务为中心的设计

在此方法中,设计人员牵扯到展示(作为服务或一组服务)预期的业务或应用程序的功能。在此种情况下,我们不必要知道服务的客户会选择什么来利用服务,但我们知道此种客户期望的交互类型。因此,与第一个情境相反,消息是次要,并且被作为对操作的需求响应被开发。

该方法的实例是由 Amazon 和 eBay 表现的 Web 服务 API(Web Services APIs presented by Amazon,AWS)13。此服务接口没有将业务过程强加于客户,一般地,它们甚至没有将所期望的接口强加于客户,但它们使第三方开发人员以清晰直观的方式接触到了各自的服务供应商的操作。

如前面所提到的,以服务为中心的建模通过了解参与者的需求(服务的外部客户)并提供支持那些需求的操作(浏览目录、向购物车中添加物品、付账等)有助于用例驱动的方法。

成为次要关注的消息的问题在 Amazon API 中是明显的,在 Amazon API 中肯定能够将普通的方案定义从当前设计中分析出来,这证明消息是为每个操作请求和响应而分别开发的。

情境

此处我们的实例是一个为化学加工行业提供零件的在线供应商。商家可以提供一个 Web 门户,客户可以通过该门户购买零件,商家还可以通过电话和传真管理进一步的业务。但需要为客户提供通过比 Web 本身更程序化的方法对购买门户进行的访问。这种对核心订购功能的访问使公司成为客户供应链中的关键要素,一个可以直接与客户核心业务应用程序集成的要素。商家试图实现 EDI 购买解决方案,但初始部署的成本和必要的基础结构证实是不可行的的。执行团队相信许多客户正在向其他的能够提供此种购买门户的供应商转移,因为这些竞争者已经能够通过更自动化的过程更好地集成。

与我们的第一个情境比较,此项目由 IT 组织推动。以一个商家的观点,项目目标是简单地提供一个机制来执行同样的订购操作,不需要让客户花时间将数据输入到 Web 门户或者商家输入来自传真订购清单的类似数据。IT 组织被允许独立做出许多决定,只要能够生成比前一个 EDI 尝试花费少的解决方案。

两个重要的影响设计的观察已经由 IT 组织的高级团队做出来了。

  1. 提供的功能必须不得少于通过 Web 或人工订购提供的当前功能。

  2. 操作集不是由我们的业务过程所推动,而是由客户所使用的,作为他们过程的一部分。针对该原因,我们必须假设关于这些操作使用的可能性越少越好。

软件架构师生成了一组描述客户所期望的功能的用例文档,并且确保业务团队同意。然后用例被断成一组离散的操作,且数据需求(消息)被指定。这些操作集合成一组三个用于搜索、订购和账户管理的服务。此步骤倾向于受到经验和判断的影响比受到精确的规格影响要多,因而此步骤是迭代的。

一旦知道了服务和操作集,团队就可以更加正式地定义服务规范,包括针对每个接口的协议和服务客户所需要的任意策略信息。该步骤非常的重要:它向客户提供了在服务可用时,不能够通过简单地阅读由商家部署的 WSDL 就能够被理解的信息。

活动

业务执行者(不是当前的 RUP 角色,但似乎我们都承认他们)传达了这样一个需要,就是当客户感觉他们的收入正在被当前提供这些功能的更大的供应商抢走时,必须向客户提供可编程访问业务服务的能力。

软件架构师打算开发一组提供 Web 订购系统的核心功能的服务。提议包括一组用例,描述了客户通过 Web 执行的活动(与来自在线业务的业务分析人员一起开发)。同时也包含了初始阶段的模型,这个模型展示了对于当前后端系统的候选服务和他们之间的关系。

软件架构师,赞成该项目,迭代候选服务模型以在后端应用程序分区(公然地展示所需的业务功能以支持服务)中识别服务。同时,软件架构师让设计人员观察当前的 Web 应用程序及如何与后端系统交互,挖掘出要由服务实现的任何所需的业务逻辑和需求。

软件架构师和业务分析人员一致同意把所需的功能集作为服务执行的操作和任意所需的约束或策略来提供。此模型的迭代显示了三个具体的服务和初始服务规范,尽管在过程的这一点上这些只指定了服务的结构方面。

软件架构师与 Web 应用程序团队的开发人员一起了解对于已识别的操作集的具体数据需求。这被交给了具有 XML 技术的数据架构师,来开发将会生成由操作销毁和生成的消息方案的消息模型。

设计人员可以开始连接服务模型和将用来描述提供业务逻辑的组件的实现模型(J2EE)并连接到现有的后端应用程序。

软件架构师和设计人员最终用细节根据服务规范细化了服务模型,主要提供可以使客户了解如何与服务交互的协议和策略细节。

我们现在有一组完整的模型:

  • 描述客户期望的用例模型

  • 描述客户视角(服务规范)和供应商视角(服务、分区等)的服务模型

  • 描述实现服务规范的软件组件的实现模型

现在开发人员能够实现准备由客户使用的试验系统。

继续的行动

在成功部署试验工程之后,要注意的是,向客户提供的服务涉及 Web 系统特定功能的并行实现。建议建立新的工程来重新配置 Web 应用程序以复用这些服务,这项工作应该包含于 Web 应用程序的常规计划更新中。这样的重配置将某些业务逻辑从 Web 应用程序中移到服务中,因而一个单独的组件集合由基于 Web 和服务的客户使用。

为了满足 Web 应用程序团队对性能的关注,除了向合伙人提供的 SOAP/HTTP 绑定之外,服务还需要被重配置,以在 Web 应用程序中访问服务时,服务能够提供更有效的 Java 绑定,。

3. 以协作为中心的设计

在协作为中心的方法中,重点是两个或多个服务的协作,这是服务的过程视角,它与传统业务建模的相关性要比与软件开发活动的相关性更大。在此方法中,服务作为协作中的实现角色,因此服务规范成为为跨一个或多个协作的角色而定义的责任。

这样一种方法将对那些涉及到 RosettaNet Partner Interchange Processes(PIPs)的开发和 OAGIS14标准的开发中的人是可识别的(然而,在这些情况下协作远不完全)。这样的方法在业务中对于业务过程设计或在业务集成活动(在活动中 IT 系统的组件作为服务出现)中而言是普遍的。

通常在这样的情境中,服务规范可能直接源自协作,而该方法倾向于较少关注于导致需要实现完整性的混合方法的消息内容。

情境

此情境涉及一个已经决定通过收购而继续扩充策略的中型银行企业,这意味着对于该企业来说,IT 不只是一个必须拥有的部分,而且还是在吸收所收购操作过程中发挥竞争优势的业务的一部分。

银行已经开发了一个领先的得到谨慎管理的组合,以确保成本和功能的效率。然而,很清楚的是某些技术和文化方面的阻碍出现在视线中,在整个企业中提供应用程序的一般集合。由于这些阻碍,公司已经决定使用服务方法来提供它们的 IT 功能并以此式样开发所有的新功能。企业已经经过多年开发了一套以过程为中心的东西。这些很好理解,一般的过程使它们有效地集成所收购的企业并指导他们的 IT组织来支持这些过程。

在我们的情境中,银行将一个遗留应用程序引入了服务组合中,这给我们提供了一个机会来观察帐户统一的过程模型,即一个令企业帮助客户有效利用帐户的业务服务。此过程模型已经由许多“黑盒子”活动设计而成,意味着一个活动通常由一个没有作为服务组合的一部分而启动的系统执行或者以还没有细化的方式执行。模型将这些活动表示为“黑盒子”并不提供更多的细节。团队已经注意到特定的遗留应用程序系统参与了帐户统一过程的三个活动,且其他过程模型的分析揭示了使用同一应用程序的两个其他的过程。

在企业所依靠的方法中,过程模型是分析和需求收集的主要工件。过程本身表现出通过 IT 和相应的人员,业务功能需求的完全体现,附属的且正式定义的文档描述了非功能的需求。在配置管理之下这些过程模型得到了小心的维护,并且为每个操作过程而发布,这样它们不仅指导过程的开发还为过程中的银行职员培训提供了材料。

早期提及的服务组合是一个 RAS15存储库,其考虑了基于由每个资产中的 RAS 名单所定义的标准的搜索。资产是所部署的服务,而名单包含了描述服务的核心组合及描述业务信息(如所有权、策略等等)的范围。

在开发服务以提供遗留应用程序的功能过程中,包含了业务和 IT 代表的团队致力于作为业务过程实现的服务之间的协作。该方法使业务端将结果看成是传统的业务过程模型,而 IT 端将同样的模型看成是服务之间的协作。

活动

业务分析人员要么创建新的业务过程模型,要么更新现有的业务过程模型。此模型是按照商家所展望描述的新过程,该过程更新还包括由过程活动管理、消除或产生的业务文档定义。软件架构师创建了差距分析文档,这个文档对新业务过程的需求和现有服务组合进行了比较。

业务分析人员将关键性能指示器(Key Performance Indicators,KPI)16定义为业务过程本身的一部分。这暗示着参与过程的服务必须支持可以查询的用来确保与 KPI 的一致性的度量。

数据架构师改进来自业务过程模型的消息定义,确保与现有方案的通用性,然后开发可以用于生成服务所需的 XML 方案的消息模型。

软件架构师用新的服务或向现有服务中添加新的规范来更新服务模型。数据架构师开发的消息模型用于(或复用于)这些服务规范。

软件架构师和业务分析人员更新早期定义的过程模型以将活动映射到新的或更新的服务上。对于服务更新,模型是完整的了,现在就可以对其进行转换并发布。

软件架构师和设计人员开发了包含协议和策略信息的具体服务规范。这样一个具体的规范作为供应商和客户之间的合约,不能由任何一方打破。

开发人员创建针对遗留应用程序的适配器和/或变换,用来实现具体的规范。

开发人员必须开发用于监控的度量生成器。这些通常是具体的操作,需要监控基础结构来查询对应一般状态和度量状态的服务。

集成专家使用新的服务来更新过程的编排 —— 在此种情况下,业务过程被转化为编排语言,业务过程执行语言(Business Process Execution Language,BPEL)。在某些情况下,在部署之前还要用一些额外的信息更新生成的编排。

业务分析人员用业务 KPI 定义和它们到具体度量的关系来更新监控中间件,以便可以监控新的服务。







接下来的步骤

IBM Rational 团队已经与许多客户一起工作,并在IBM 的内部项目中展示并使用了 RUP 和 RSM/RSA 插件。我们已经收到足够的反馈信息,通过这些信息我们得知尽管我们还有许多事情要做的,但我们已经建立了良好坚实的基础。现在我们正致力于一组具体的工程,其设计用来延伸我们所做的工作,并且了解我们可以在哪里添加更多内容,特别是在用于建模工具和额外的 RUP 指导主题的策略规范的领域。

posted @ 2006-04-17 03:58 wsdfsdf 阅读(197) | 评论 (0)编辑 收藏

SOA 探索,第 1 部分: 通过动态解耦来简化 Web 服务调用-----执行稳定的 Web 服务调用的解决方案

学习如何使用应用动态代理模式(Dynamic Proxy Patterns)来进行动态解耦的 Web 服务适配器(Web Service Adapters)。通过适当地使用这种机制,您可以提供所需要的抽象级别,这样有助于适当的面向服务的体系结构(Service-Oriented Architecture,SOA)的实现与服务重用。

引言

理想的基于面向服务的体系结构系统设计的需求是在服务消费者与服务提供者之间进行解耦。解耦可采用多种形式,其范围从静态(在编译时通过请求端存根来解耦)到全动态解耦(在所有服务调用的运行时完全封装并建立解耦)。显然,全动态解耦是一个严格的要求。如果一个服务被动态解耦,然后服务特性中的更改导致了服务实现中的修正,但是所有其它的系统元素,特别是调用机制,仍旧保持不变。这种设计的优点显而易见。

对于 SOA 与 Web 服务的更强大功能与性能的日益增长的期望与需求经常导致显著增长的软件复杂性。今天,SOA 实现的实际情况是,尽管规划了服务的功能模块化,但是它们仍旧经常与独立的中间件或通信协议(如基于 MOM 的 JMS、HTTP/SOAP 等等)耦合。在大多数组织中,当应用程序扩展功能时,开发者关注的,在某种程度上,是静态解耦(通常是指绑定),并强制为每一个 Web 服务创建独立的客户端,而不是单独的能够同时访问多个服务的客户端。

静态绑定的局限性是非常明显的——代码中的静态绑定阻止了不同应用程序中贯穿整个企业的服务的重用。简而言之,即使需要提取并封装所用的不同中间件及协议来执行服务组件之间的交互,这些组件被包括在服务消费者与服务提供者的交互中,这样的需求非常普遍,但是封装了 Web 服务接口的体系结构还未得到广泛应用。造成这种状态的其中一个主要原因就在于,尽管动态绑定的几种机制已被设计用来适应这种局限性,但是对动态绑定相关联的实际技术依然存在很多的误解。





Web 服务调用的剖析

已经有许多关于 SOA 最重要的概念——服务接口(换句话说,调用功能)及在运行时如何定位并调用它们的文章。换句话说, Web 服务调用应该在后期绑定。需要指明的是 Web 服务调用已经被设计为传统的 Remote Procedure Call(RPC)方法,该方法准许一个应用程序调用由第二个应用程序发布的功能。RPC 工作方式如下(如图 1 所示):

  • 被调用的应用程序的功能是以本地功能的形式展示给调用的应用程序的。
  • 通过向调用的应用程序提供功能存根达到定位透明性。
  • 功能存根,当它被调用时,访问一个中间件层,该层向被调用的应用程序传输调用及其相关的数据。

图 1. 基于 RPC 的 Web 服务调用
基于 RPC 的 Web 服务器调用

在 Web 服务中,存根代码通常是自动产生的,并且是基于使用被调用的功能的接口描述,它通过 Web 服务描述语言(Web Services Description Language,WSDL)来表示,并创建了存根 shell。此外,存根通常是在应用程序开发的编码阶段产生,因为存根是主要是从应用程序代码中直接调用,而且,结果是必须在编译时解决的(换句话说,即所谓的前期绑定)。

大多数应用程序开发者,主要是 Java 开发者,认为使用这样的存根是必要的,因为对他们来说,如何处理从调用服务返回的复杂数据类型是不清楚的。当然,来自被调用应用程序功能的数据必须同 SOAP 消息相分离,而且,当使用 Java 的时候,必须有一个相对应的(兼容的)实现序列化接口的类。显然,同样的存根产生工具被用于产生那些所需求的类。

本文的首要思想就是,一般来说,通常自动化是双刃剑。一方面,自动化准许行业内 Web 服务的快速适应,其原因是,有了自动化工具,大多数应用程序开发者的行为不再发生在 WSDL 自身的级别上。另一方面,不幸的是,市场仍需要一种主要的工具来选择需要使用的调用形式——显式的存根(存根在编译时解析)或隐式的存根(存根在运行时解析)。隐式的存根通常被当成 Web 服务的无存根调用。

大多数基于 Java 的 Web 服务工具提供了一些 Web 服务接口的运行时后期绑定功能。来自 webMethods 的 Glue 产品与 J2EE Web Services Developer 组件的 JAX-RPC 包就是两个例子。然而,这些尝试大多导致了软件深受供应商特定逻辑的影响。而且,问题并不仅仅存在于供应商指定的代码。在许多情况下,供应商专有的解决方案产生了实际的可管理性与可维护性的问题。

现在让我们回顾提到的问题点,例如用于后期绑定的 webMethods Glue 方式。目前,Glue 是广泛使用的工具。由于使用了一个代理用于 Web 服务的接口,Glue 看起来好象是无所不能。然而,仅仅通过自身使用一个代理并不能消除所有的问题。下面的 Java 代码片断描述了在它们的应用中的一个典型的负面情形:


清单 1. lateBindingGlue
												
														public class lateBindingGlue 
{ 
public Document serviceInvocationGlue() 
throws Throwable { 
String wsdlName = "http://…../Service.wsdl?WSDL"; 
String operation = "…….."; 
String args[] = {  }; 
/* first, Glue creates a SOAP interceptor */ 
SOAPInterceptor responseHandler = new SOAPInterceptor(); 
/* second, Glue registers the SOAP interceptor to catch incoming responses */ 
ApplicationContext.addInboundSoapResponseInterceptor( 
(ISOAPInterceptor)responseHandler ); 
try { 
/* third, Glue gets a proxy to the Web service through its WSDL */ 
IProxy proxy = Registry.bind( wsdlName ); 
/* here, service's operation is invoked through a proxy */ 
proxy.invoke( operation, args ); 
} catch( java.rmi.UnmarshalException e ) { 
// Glue is catching the UnmarshalException that is perfectly expected 
} 
/* forth, Glue generates an XML document containing the SOAP body, */
/* and passes the whole document for parsing  */ 
 return new Document( responseHandler.getResponse() ); 
} 
} 
class SOAPInterceptor implements ISOAPInterceptor { 
private Element soapBody; 
public void intercept( SOAPMessage message, 
Context messageContext ) { 
try { 
soapBody = message.getBody(); 
} 
catch( Exception e ){ 
 System.err.println( e.toString()); 
} 
} 
public Element getResponse(){ 
 return soapBody; 
} 
} 

       

												
										

您能从上面的例子中学到很多东西。首先,由 Glue 引入的代码是一个两层代码。一层“消除”了 SOAP 分离的负面效应,通过使用 Java 异常处理程序和一个专门的组件——SOAP 拦截器来拦截这种特定的应用程序异常而实现。第二层将服务调用的结果作为完整的 XML 文档来提交给调用应用程序。然后,XML 文档通过使用一个诸如 DOM 结构的工具进行分离。显然,这样的方法不能“安全地”移植到其它 Web 服务工具中。但更重要的是,尽管拦截应用程序异常的技术广为人知,但它真的适合于 Web 服务调用吗?

一般而言,异常是 Java 语言极为有用的特性,特别是,这意味着一种检测错误位置、无计划的编程操作(如使用空指针)的简单方式。使用这种技术作为一个计划的控制操作,而不是写一个 if-then 逻辑段来测试一个指针是否真正为空,使代码的可管理性与可维护性显著地复杂化。显然,SOAP 分离并不同于空指针。您不能通过一个简单的 if-then 代码测试出来。不过,它们的负面影响是相同的——抛出异常并捕获它,这是一项代价非常高昂的技术,特别是如果您需要获得每秒数千次的 Web 服务调用的话。换句话说,运行时异常应该专门针对意外情况作为“防御线”而保留,以应对软件的错误。

我进一步指出为什么分离 SOAP 的问题不能通过一个 Java Exception API 进行处理的更多原因。但是,让我们先来看看引用的范例所显现的另外一个问题。由于调用操作需要直接分析 XML,它不得不访问响应信息的 XSD 定义,而且必须依次成为提供的 WSDL 文件的一部分(且被存根产生工具所使用)。这里的最终结果就是甚至一些后期绑定的形式也存在于引例之中;在 Web 服务伙伴之间的紧耦合依旧存在。换句话说,Web 服务的客户端必须访问 WSDL 文件,并且在大多数情况下,它必须是一个完整(而不是部分)的 WSDL 文件。

还存在一个与使用 JAX-RPC API 相关的问题。记住这是非常必要的:在 Java 语言中,由于在 XML schema 中的数据类型不能直接准确地映射到 Java 语言的数据类型当中,所以在调用的应用程序端 WSDL 中产生的服务终端接口将与 JAX-RPC 编译器在调用端产生的 WSDL 的形式不同。而且,生成的服务接口也将依赖于 SOAP 采用的编码体制。例如,使用文档文字编码利用了每个方法类的封装版本,并造成了额外的可管理性与可维护性的问题。





Web 服务编程构件的自由应用程序逻辑:最佳实践设计模式

根据到目前为止的讲述,您容易想到使用任何种类的动态调用技术(如后期绑定的动态代理),不幸的是,许多开发者都是这样做的。关于 Web 服务其中一个最常见的误解就是,使用动态调用取代静态存根的好处并没有那么大,而且最好是坚持用生成的存根作为 Web 服务调用的主要方法。

最后,我们的讨论转到第二个,而且是最重要的原则——它不是真正的编程技术,它确保不依赖服务编程构件(如 WSDL),但是取而代之的是,它的价值体现在高级设计中。这对于获得 SOA 的真正利益是必要的,因为随着服务的发展,服务消费者的代码将完全不受影响。无论如何,基于 SOA 的应用程序必须注重于提供弹性体系结构,且更少的关注于公共通信协议(比如 SOAP)。服务与应用之间不应该具有严格的界限。一个终端用户的应用程序可以被看作是其它终端用户的服务。整个企业 IT 环境应该被设计成高度模块化,允许开发者能够挑选适合他们需要的服务与应用组合。

在良好的 SOA 设计中,Web 服务消费者的应用逻辑能够使用两个基础体系结构原则来从服务构件完全解耦:

  • “保持可适应性”——创建一种方法来支持多接口继承(理论上,这将不受限制),在开发有限数量的具体实现(在面向对象的设计当中,经常将匿名的内部类作为对象适配器使用,考虑上下文,允许工作行为的定制,实际上是嵌入在子类之中)。
  • “使用所谓的好莱坞原则:不要调用我们,我们将调用您”——Web 服务调用模型应该只通过动态代理框架来指定发现,并假定客户端事先对服务一无所知;因此,Web 服务提供方应该能够通过将存根类信息声明到 XML 文档,从而在运行时宣传他们的服务。那实际上就以一种开放且可执行的方式,提供了发现之外的另一种调用方法(换句话说,优于 UDDI)。

最终设计目标是,为 Web 服务消费者应用提供一组类,这些类根据上面引述的原则组成了可重用适配器层。这种适配器层封装了使用存根及其生成的类的代码。适配器的公共 API 并不公开任何存根类;而是将其映射到 Web 服务消费者应用可以理解的类。

为了得到最好的适配器灵活性与可扩展性,适配器的总体类结构均通过使用下列设计模式的组合来构建:

  • 动态代理是一种结构模式,它定义了一组类与方法调用,这些类和调用被分派给调用句柄(在动态代理类生成的时候指定)。使用动态代理是 Java 编程中模拟多实现继承的关键。通过动态代理,定制的 InvocationHandler 能够由一组表示合成子类的超类来构建;该子类的接口将是这些超类实现的接口的联合。
  • 适配器是一种结构模式,它通过对实现的抽象进行解耦来影响类层次(比如继承层次)的创建,因此两者可以单独改变。这种允许在运行时选择实现的解耦避免了抽象与其实现间的永久绑定。作为 Web 服务客户端的调用应用的类仅处理抽象。
  • 服务配置器是一种行为模式,它使您可以改变适配器超时性能,并添加或去除附加功能,这样就改变了调用框架的规范。例如,如果一个 Web 服务提供方引入了一个新的协议(如在 RMI 上的 SOAP),那么它只需要“宣传”新的传输性能。因此,适配器演示了这种新服务能力与这种调用功能的任何实现。使用一些元数据表示作为结果,必须具备一种方法能够引用提供了独立于特定规范与实现的功能类的接口。
  • 工厂方法(Factory Method )是一种结构模式,它使一个类延迟实例化到子类。在 Web 服务调用的情况下,本地与远程实现类都必须是子类,以实现它们的特定于服务的实现。需要访问服务的调用应用将得到这个工厂的一个句柄,并给服务一个调用。因此,根据从服务配置器得来的信息,工厂封装了访问服务必须使用的实现知识。
  • 装饰(Decorator)模式是一种结构模式,它定义了缓存、发布与交换服务声明的封装器,用于连接合适服务与可重用的代理类。 通过使用装饰模式,实现执行调用的代码与提供缓存的代码相分离,将非常简单。




关键实现指南

图 2 演示了使用上面引用的设计原则而设计的“好莱坞”类型适配器的概念模型。 图 3 展示了使用适配器时的基本交互的序列图。


图 2. Web 服务适配器的概念模型
Web 服务适配器的概念模型

图 3. 包含 Web 服务适配器的序列图
包括 Web 服务适配器的序列图

创建一个使用适配器的服务,包括创建一个使用服务描述符(代表 SOAP 服务)的服务类。这个描述符被包括在服务类成员之中。服务类被作为 SOAP 来部署,例如,使用来自 Open Source Foundation 的 Axis。

服务描述符包括:

  • 类名:包含服务实现的全限定类名的元素。
  • 名称:包含服务名的元素。
  • 版本:包含服务版本名的元素。
  • 创建者:包含服务创建者名称的元素。
  • AssertURI:包含指向一个 XML 文件的统一资源标识符(URI)的元素。其中,XML 文件包括服务声明(规范)。
  • 描述:包含服务描述的元素。

现在,有一个关于 Axis 的耦合注意事项。使用 Axis 作为 SOAP 引擎非常有助于实现 Web 服务的松耦合,理由如下:

  1. 因为 Axis 定义了消息处理节点,该节点能够被封装以供服务请求者(客户端)与服务提供者(服务器)使用,适配器能够使用部署描述符作为一个 Web 服务部署描述符(WSDD),应用一个消息处理节点来部署 SOAP 服务。
  2. Axis 中的服务通常是 SOAP 服务的实例,它包含请求与响应链,但是必须包含实际服务类的提供方。结果是,通过将消息上下文传递给消息处理节点来完成 SOAP 服务的处理。
  3. Axis 客户端处理能够通过使用服务描述符和 XML 声明文件创建包含服务细节的调用工厂实例,从而构建调用对象。调用对象的属性被设定为使用相关的目标服务。然后,调用对象就通过调用 Service.createCall 工厂方法来创建。一旦建立起调用,Call.SetOperation 就通过被调用的方法名称来指定。然后,Call.invoke 通过相关的请求消息而被调用,它驱动 AxisClient.invoke,处理结果消息上下文,并向客户端返回响应消息。

在适配器的设计中,应该对性能进行特殊考虑。使用动态代理类具有性能含义。访问目标的直接方法快于访问代理类的方法。然而,这不应是在稳健体系结构与性能之间进行选择。这就是为什么目前适配器实现缓存封装器的原因。通过应用缓存,使用静态存根与基于适配器的解决方案之间的差异相对较小。根据如何实现缓存,必须提到可能的解决方案之一——记忆(Memoization)。 记忆是一种广泛使用的技术,它在 Lisp、Python 与 Perl 这样的功能编程语言中使用,给功能赋予预先计算的值。记忆一个功能将为功能添加一个透明的缓存封装,因此已经得到的值将从缓存中返回而不是每次都重建。记忆可以显著提高动态代理调用的性能。

总结我们关于此处描述的适配器的讨论,允许支持本地和远程服务实现的设计是非常重要的。服务类对适配器来说将是本地的,而远程 Web 服务则可以相互替换,因为服务类和代理类使用同样的接口来访问远程 Web 服务。本地服务类将实现与 Web 服务器远程实现相类似的方法 getFunction() 来返回功能的结果。下面的 Java 代码片断进一步说明了这一点:


清单 2. 本地服务类及其接口
												
														public class LocalServiceImpl implements IService
{
/* get the service results */
public ….. getFunction() 
{
………..
return …………;
}
}


												
										

实现了 IService 的代理类采用了方法 getFunction(),但并未考虑该方法需要访问远程 Web 服务的代码。这些代码代表了需要用来访问部署在适配器内的任意 Web 服务的代理代码。


清单 3. 远程服务
												
														public class RemoteServiceImpl implements IService 
{
/* get the service outputs */
/* outputs are from the web service running in the location */
/* mentioned in the serviceURI */

public ….. getFunction()
{
adapter.examples.Function service = null;
String serviceURI = "http://……../Function/";
String wsdlURI = "http://localhost:8080/Function/";
Try
{
// init the lookup
WebServiceLookup lookup = (WebServiceLookup)
……….
// get the instance of the Web services interface
// from the lookup
service = (adapter.examples.Function)
lookup.lookup(wsdlURI,
adapter.examples.Function.class,
serviceURI);
}
catch (Exception e) 
{
e.printStackTrace();
}
// now, call the methods on your Web services interface
return service.getFunction();
}



												
										





结束语

显然,使用 Web 服务的静态存根与前期绑定是 Web 服务调用的最简单的形式。但是简单化也带来了明显的缺点。与紧耦合方法不同,使用本文提出的适配器方法将给您留下可高度重用和可配置的 Web 服务代码。由于 Web 服务 调用全部通过部署了服务描述符的公共适配器来引导,因此您能够动态地决定调用什么服务——在部署代码时或在运行时。

同样,那些可能寻找商业产品作为 Web 服务松耦合调用定制解决方案的组织应该研究企业服务总线(Enterprise Service Bus,ESB)技术(参见参考资料),该技术提供了类似于上面所引述的功能的选项来连接企业内部及跨企业的可作为 Web 服务的应用程序,并具备一套功能来管理并监视已连接应用之间的交互。

posted @ 2006-04-17 03:56 wsdfsdf 阅读(232) | 评论 (0)编辑 收藏

基于 SOA 构建网格应用程序-----SOA 幕后的概念,以及如何将网格应用程序迁移到 SOA 模型

网格和面向服务架构(SOA)是两个似乎相互冲突的系统。SOA 是构建离散服务的标准,它可能要跨越多台机器,这些机器可以进行合并以构建一个应用程序,从而降低集成成本。大部分现代网格都采用了类似于 SOA 的 Web 服务,但是在这两个系统之间实际上有更多东西可以进行合并,而不仅仅是采用几个 Web 服务。您还必须调整网格解决方案的体系结构。本文将简要介绍 SOA 幕后的一些概念,以及在将网格应用程序迁移到 SOA 模型时应该考虑的问题。

迁移到 SOA 和网格

网格应用程序的一个永恒的问题是,使其足够灵活,以在各种平台和环境中使用。尽管早期的网格使用了专用的解决方案,其中采用的是严格受控的硬件和环境,但是最近的发展已经清楚地表明,将网格应用程序放到更为广泛的平台上运行,这样您只需要添加一些机器就可以很容易地扩展网格的范围和处理能力。

然而,平台之间微小的差异可能会导致非常令人头疼的事情。例如,Windows® 不同版本之间的改变,甚至是 Windows NT 和 Windows 2000 之间的差异,也都会导致那些网格环境中通常经过严格设计和优化了的应用程序出现问题。一个显然的解决方案是去掉那些高度与平台相关的元素,并切换到一个更加通用的环境中。

SOA 幕后的准则遵守一些基本的规则。SOA 是一个用来构建应用程序的基于组件的模型,可以将应用程序划分为很多离散的服务,这些服务各自执行某个特定的功能,但是可以将它们组合在一起构成更大的应用程序。

SOA 的基本原理现在已经并不新鲜了。面向对象的概念已经出现了很多年,分布式对象也已经在很多技术中存在很多年了,例如 CORBA。主要的区别在于,SOA 是基于面向对象和 Web 服务两个概念的组合,并在一个用来描述可用接口的开放系统中采用了这种结构。通过使得 Web 服务可以更容易发现和识别,SOA 可以极大地简化基于 SOA 应用程序的部署和分布。由于 Web 服务都是基于开放标准的,在其定义中就保证了体系结构和平台的无关性,因此基于 SOA 的应用程序可以部署到各种平台上。

简而言之,SOA 是一种对外提供服务的方法,让计算机可以彼此进行交谈,并共享自己的处理能力和功能。网格正在慢慢地朝 Web 服务架构发展,首先是 Globus 采用开放网格标准基础设施(OGSI),然后是发布 Globus Toolkit 4.0(GT4)。SOA 和网格技术正基于诸如 Web Services Resource Framework(WSRF)以及其他的一些解决方案,朝 Web Standards Interoperability 技术方向发展。

您还可以看到 SOA 和网格都可以为对方提供很多东西。这并不是网格技术利用 SOA 准则的情况,或者反之。从 SOA 的观点来说,网格为信息和资源的分布提供了一个异常模型,这是 SOA 模型的一个关键特性。从网格的观点来看,SOA 为调整网格解决方案的架构以及促进其透明性和更好地支持广泛的平台和环境,提供了一些可选的而又非常灵活的方法。

下面让我们来了解一下传统的网格模型,然后介绍一下基于 SOA 的网格模型,从而比较二者之间的区别,以及如何开始将网格和 SOA 应用程序作为一个单一的资源进行考虑。







传统的网格模型

为了全面地理解 SOA 如何才能改进网格服务,以及需要如何修改应用程序,下面让我们来看一个基于传统的网格技术的典型网格服务,包括基本的 Web 服务。这个服务的基本结构非常简单。

在图 1 中您可以看到一个典型的网格环境的结构图。其中我故意没有说明网格软件的类型,因为大部分网格软件都可以根据相同的原理进行工作。


图 1. 网格模型结构图
网格模型结构图

总体上来看,这个结构相当简单。我们有一个网格协调者负责分发信息并与各个节点进行工作。这个协调者(它还有很多别的名字,包括分发和管理节点)的职责就是运行网格。协调者与工作节点之间的通信可能在很多解决方案中都存在,不过大部分系统(包括 Globus)都是依赖于 Web 服务的。此处使用的模型通常都称为级联服务,因为信息和工作请求都是通过服务进行级联,从而将其从某个地方分发到各个节点上。

然而,不管采用哪种通信系统,其方法大体上是相同的:

  • 严格结构的意思是说,节点都是使用一个特定的 Web 服务或 Web 服务接口与某个软件的特定部分进行联系的,从而处理来自节点协调者的请求。
  • 任务提交是通过协调者进行处理的,它分布在各个节点上,通常使用一个 Web 服务来提交任务。在工作节点上,有一个类似的客户机将完成的任务发回给网格协调者。
  • 网格节点所需要的其他信息(例如大型的数据结构或引用材料)可以在网络上通过另外一个服务进行访问,Web 服务可能支持,也可能不支持。例如,有些网格使用一个集中的 SQL 数据库来存储节点不通过 Web 服务接口而是直接访问的信息。

总体来说,大部分网格服务(直到最近)都是基于大型的单一代码基础的,它使用了一些私有的方法来进行通信和共享信息。这使得 Web 服务模型也正在发生改变,但是即使采用了 Web 服务标准之后,很多解决方案也都可以对原有的单一应用程序使用一个 Web 服务接口。例如,从上面这个传统的模型中我们可以看出,将任务提交到一个节点是通过一个 Web 服务接口提交给网格节点的,这实际上会将面向 Web 服务的接口暴露给原来的应用程序。

这种单块方法存在一个问题,即使使用 Web 服务,它也会限制扩展和增长的能力。采用这种单块风格,将应用程序移植到其他平台和环境就会变得更加复杂。如果您的系统不是基于 Web 服务的,那么问题可能就更加严重。增长之所以会受到限制是因为它依赖于单个协调系统来负责在网络间分发信息。如果您的客户机也是一个单块接口(即使它同时还使用 Web 服务来提供接口),那么将网格应用程序部署到很多机器上也会变得更加困难。







SOA 应用程序模型

SOA 并不是使用 Web 服务来集成应用程序不同部分并在其间进行通信的另外一个简单术语。SOA 要走得更远,它定义了一种方法来部署应用程序,这样可以将注意力从由多个函数和对象组成的单个应用程序转移到一种将整个应用程序划分为多个单一服务的结构上来。例如,考虑一个记帐程序,它有一些组件负责开具发票并提供一种方法进行支付。除了传统的组件应用程序模型之外,您还可能会希望为这两个任务定义一些对象和相关方法。

在一个简单的 Web 服务环境中,您要为对象和方法构建一个接口来允许访问需要远程访问的内容。例如,开具发票这个任务可能需要您通过网络连接进行访问。在所有的可能性中,Web 服务都会在一台专用的机器上有一个专用的接口,为其构建一个接口需要了解这台服务器上都在运行什么服务,以及为其提供接口需要的详细信息。

在一个 SOA 中,这个记帐应用程序中的每个功能从技术上来说都可以作为一个 Web 服务。每个服务都会在网络上广播自己的存在,您可以在任何经过适当授权的机器上执行任何操作。而且,由于每个服务都是自己可以控制的一个组件,因此它们可以存在于网络上的任何地方。我们不再需要一台专用的服务器来处理请求。例如,我们可以使用一个服务器农场,由于服务会广播自己的存在,因此我们不必担心如何发现这些服务。

从上面的介绍中,我们可以确定 SOA 的主要元素是:

  • 可以作为一个单独的服务使用 —— 所提供的服务质量的级别还需要作为一项标准确定。例如,我们还不知道是否要提供一个可以处理多个操作和多个服务的单一发票服务,每个都支持不同的操作,例如开具发票、支付发票或修改发票。
  • 独立性 —— 我们并不关心它们是如何来实现我们请求的任务的。它们只要实现这个功能就好了。类似地,服务也并不关心如何来达到这个结果。
  • 服务会广播自己的存在。

因此从理论上来说,应该可以将一个应用程序划分为更小的组件,然后可以将其连接在一起(通过相互调用),从而构成最终的应用程序。由于这些单元也可能会扩展到多台机器上,因此我们需要从这种单块、级联结构切换到一种更加灵活的分布式、自由通信的结构。在图 2 中您可以看到一个 SOA 结构的例子。


图 2. SOA 网格模型的一个例子
SOA 网格模型的一个例子






SOA 网格模型

从上面对于 SOA 模型的介绍以及目前网格技术朝着 Web 服务结构发展的趋势可以清楚地看出,二者正在不断融合。使用简单的术语来说,网格是一个共享资源的分布式系统,而 SOA 则是一个分布式体系结构,后者最关注的是服务的相互操作能力、易于集成、简单性、可扩展性以及安全访问的特性。这两个系统有一些共同的问题,包括延时、并发和局部故障等问题。

二者都使用了 Web 服务,图 3 给出了一个可以在 SOA 和网格环境中使用的简单布局。二者都大量地采用了 SOAP、XML Web 服务标准以及相关的安全性、管理和其他系统。


图 3. SOA 操作模型
 SOA 操作模型

不管现有的应用程序是否使用 Web 服务,您都可以看到在图 3 中详细介绍的开放标准构成了 SOA 标准的主体。总之,SOA 利用了以下的技术:

  • 使用 XML 来构成所有标准的核心部分,从用来交换信息的 SOAP 协议到用来共享描述信息的方法。例如, WSDL(一种基于 XML 的描述语言)就用来描述潜在的客户机可以使用的服务。
  • SOAP 为交换对象和调用方法提供了一些基本的方法。底层的传输协议是高度不相关的,不过很可能会使用 HTTP。
  • 很多扩展用来为服务之间的交互操作提供关键的服务。例如,WS-Reliability 和 WS-Resource 就用来帮助提高通信的可靠性。
  • 后台标准,例如 WS-Security 和新的 WS-Distributed Management 标准,用来帮助提供安全的通信和管理远程服务。

这些准则和技术早已在 Globus Toolkit 中得到了采用,并深入网格标准和应用程序之中。

要在自己的应用程序中采用这些技术,需要改变一下开发应用程序的方法。例如,要在网格应用程序中采用 SOA 的准则,您需要:

  • 将应用程序迁移到服务模型。如果您还没有这样做,就必须考虑一下应用程序中的每个操作。稍后我们会更详细地介绍这个问题。
  • 将应用程序划分成更小的、离散的组件。例如,不采用一个带有 Web 服务接口的单块程序,而是将应用程序划分成单个基于 Web 服务的组件。您可以将为网格节点提供服务的应用程序划分成单个服务来接受任务、返回任务和汇报统计信息。
  • 确保节点和控制器可以独立工作。不要依赖于对数据库服务器或其他资源的持久连接。

反之,要在 SOA 应用程序中采用网格的概念,您需要:

  • 从应用程序中删除那些依赖于单一主机或环境进行操作的部分。
  • 将统计信息和监视信息集成到 SOA 服务中,从而确定典型的网格负载信息,例如 CPU 和存储资源。

这两种情况中的结果应该是可以构建一个更加灵活而且实际可用的应用程序。







迁移应用程序

修改现有的应用程序是修改网格或 SOA 应用程序最困难的方法,因为您需要找到一种方法来修改应用程序,却不要极大地改变应用程序工作的方法和现有的服务。

主要的问题是要确定应用程序的组织。建立要执行的操作列表,网格中的组件和节点之间通信是如何操作的,以及各个步骤的编译次序。例如,您可能会希望制作一个提交次序的模型:当提交作业时会发生什么,当发回响应时会发生什么,当需要有关某个给定资源的状态信息时又会发生什么。有了这些信息,就可以构建一个支持这些操作所需要的服务清单了。

现在您需要考虑如何实现这些服务。SOA 和基于网格的服务方法之间有一点区别:SOA 组件被认为是无状态的,而网格则是有状态的。二者并不需要是互斥的。您可以开发一个无状态的应用程序来提供有状态的信息,这样就可以包含一个方法来记录可以汇报的服务的状态。

记住,即使是在迁移到新的 SOA 模型时,应用程序中的关键部分也是相同的。例如在 CPU 敏感的网格中,网格中执行实际工作的核心的计算函数都是相同的,访问数据结构和信息的代码也都是相同的。例如,如果您考虑一个图像呈现网格,构成原始图像描述的数据以及将这些向量数据转换成最终图像的代码(函数或应用程序)都是相同的。只有各个节点之间进行通信和发送请求的方式会发生变化。

最后,具备这些信息之后,就可以开始将应用程序迁移到新的基于组件的模型了。不幸的是,并没有什么简单的方法可以产生这些信息,现在也没有什么工具可以对此进行简化。您需要确定的很多信息都依赖于应用程序和转换应用程序时的源环境。







结束语

即使对于一个偶然的观察者来说,SOA 和网格都具有类似的目标:简化应用程序,扩充其功能和所支持的平台,可以将任务更容易地分发到多台机器上。它们当然会采用很多相同的基本组件 —— Web 服务和 XML —— 但是这些方法稍有不同。您还可以看到每种解决方案可以给另外一种解决方案提供很多优点,足以值得考虑利用这种技术。例如,网格技术的独立特性对于部署基于 SOA 的应用程序就非常有益。SOA 的灵活特性和异构特性对于网格扩充自己的平台基础来说则十分理想。

采用基于 SOA 的网格,我们可以获得很多优点。单块模型消失了。现在不再采用一个单一的网格协调者来控制各个任务单元在网格上的执行,任务可以提交到任意的节点上。当任务进行分发时,如果节点不能及时处理这些任务,各个节点应该可以将任务直接发送到其他节点上。这种自治体系结构是可能的,因为各个组件可以彼此进行交互。

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

网格实践: 在网格中实现 SOA 和 Web 服务-----使用 GT4 和 Globus Resource Allocation Manager

保持与 Globus Toolkit 的同步更新对于维持最新的网格技巧来说非常重要。本文将介绍 Globus Toolkit 的版本 4,在 Service-Oriented Architecture(SOA)和 Web 服务领域中展示这个工具包,并详细介绍 Grid Resource Allocation Manager 组件(GRAM),以及为网格作业提交、监视和控制例子创造条件的支持服务。

在本文中,我将在 Service-Oriented Architecture(SOA)和 Web 服务领域概要介绍 Globus Toolkit 4 的内容。重点介绍这个工具包中的 Grid Resource Allocation Manager(GRAM)组件(以及支持服务)—— 这是一组核心服务,可以帮助您在特定的资源上启动作业、检查状态并获取结果的实际操作。通过这个重点的介绍,我们将设置提交网格作业的一个例子中的步骤。网格作业的例子开始是以一个非常基本的例子形式出现的,然后逐渐向其中引入一些新的概念和特性,以支持更加复杂的作业 —— 最后通过 Globus GRAM 将多个作业提交给调度器。

不过首先让我们来讨论一下有关 SOA 和网格的问题。

SOA 和网格

SOA 是最近的一个热点问题。尽管这个概念已经并不新鲜,但是它却重新点燃了 Web 服务的活力。Web 服务可以通过一个使用标准协议仔细进行定义的接口为远程用户提供对程序的访问。高级的服务可以在现有的服务之上进行构建,应用程序可以通过将一系列 Web 服务连接在一起而进行开发。最后,我们还有一个非常有用的重用方法。

如果应用程序提供了一个通用的可重用服务,并且它是无状态的,需要少量的输入和输出数据,那么这个应用程序就应该打包为一个 Web 服务。为了增加重用性,甚至还有一种发现并调用现有服务的机制。这种方法对于在分布式环境中提供对常用应用程序的访问来说非常有效,因为它是基于标准协议的,例如 SOAP over HTTP。

在将 SOA 应用到网格实现上时,有一些常见的应用程序应该以 Web 服务的形式提供。然而,很多常见的应用程序都是特定于网格实现类型的,无论研究、科学方面的网格,还是教育网格。如果我们希望在这些应用程序域之间使用一些可重用的服务,那么应该区分任何网格实现中所需要的服务:

  • 安全性
  • 执行管理
  • 通知
  • 复制
  • 资源发现
  • 监视

如果我们将网格实现中所需要的服务进行合并,就会得到一个基本的网格基础设施,我们称之为“面向服务的基础设施”(Service-Oriented Infrastructure)。







GRAM 功能和服务

这种环境中的 Web 服务为支持通用的作业提交方法提供了一个基础,当您希望在相关的输入数据之间提供可执行文件时,可能要在产生输出数据的同时访问这些数据,然后在执行过程中与作业进行交互,此时这种方法非常有效。这看起来可能有些超前,但是现在的确已经有了提供这种功能的工具和技术。

Globus Toolkit 4.0 就是这样一种工具。它对一组 Web 服务进行了打包,这些服务为我们提供了一个面向服务的基础设施。应用程序关注的是某个具体的问题领域,而 Globus Toolkit 关注的则是整个基础设施。Globus Web 服务可以帮助您对分布式基础设施组件进行访问和管理。

Globus Toolkit 的 GRAM 组件提供了一组 Web 服务,它们采用了 WS-Resource Framework,其设计目标是帮助您在网格环境中提交作业和管理作业。GRAM 可以用于那些需要信任证书、可靠执行以及协调文件步骤的作业。GRAM 可以帮助实现信任证书的管理,从而提交作业,监视作业的进展状况,控制作业的执行情况,并分阶段地处理相关的数据。不同的信任证书可以用来代表不同的功能。GRAM 提供了一个可靠的执行环境,并集成了多个专门用来在复杂环境中对作业执行管理进行优化的调度器。GRAM 和支持服务提供了文件分段传输的功能,甚至还提供了在作业运行时访问输出数据文件的功能,从而有效地实现对输出数据的利用。

GRAM 调度器

当您提交一个作业时,GRAM 创建一个 ManagedJob 对象,并返回其句柄。然后您就可以使用这个句柄与这个作业进行交互,这实际上是一个 WS-Addressing Endpoint Reference(EPR)。稍后我们将讨论一个典型的交互过程,并给出几个例子;但是首先让我们来了解一下支持作业执行所使用的基础设施。

网格作业可能会消耗大量的计算周期,因此一个网格环境通常会包含很多资源集群。这些集群通常是由一个调度器进行控制的。调度器负责对资源的使用进行优化,从而按照定义好的策略来有效地执行作业。有很多调度器可以使用,其中包括 Load Sharing Facility、Condor 和 Portable Batch System。

GRAM 使用调度器适配器将作业描述语法转换成调度器可以执行的命令。除了为调度器提供一个接口之外,GRAM 还包含了一种派生新的 UNIX® 进程来启动作业的机制。这适用于小型的串行作业,它们在运行时不需要集群资源,也不需要共享内存或消息传递。在后面的例子中,我们就会使用这个简单的派生进程。

派生进程使用一个 Fork Starter 程序来启动并监视针对 GRAM 的作业进程。它还记录了一些数据,例如启动时间、结束时间以及该作业的退出代码。当提交作业时,事件会被写入日志文件中。当有重要的事件发生时,会继续在后面添加日志。这些调度器日志文件是由称为 Scheduler Event Generator (SEG)的进程进行监视的,它会让 GRAM 通过监听相关的事件并与其通信,来保持与作业状态的同步。

GRAM 支持服务

GRAM 提供了作业和执行管理服务来提交、监视和控制作业,但是这都依赖于用来传输文件和管理证书所使用的支持服务。GridFTP 所提供的文件服务用来帮助 GRAM 实现对输入和输出文件的分段传输。证书管理服务处理证书对其他服务和所需要的分布式网格资源的委托。







GRAM 作业提交

现在我们已经基本了解了这些功能和支持服务,接下来让我们讨论一下实际的作业提交系统。

作业提交的基础知识

可以使用应用程序编程接口(API)或者通过命令行工具,以编程的方式提交作业。命令行工具是用来测试 Globus 安装的一种简单方法,因此我们首先介绍一下这种方法。

globusrun-ws 命令行工具取代了 managed-job-globusrun 命令,它用来提交、监视和控制作业。它可以协调文件的分段传输、证书委托和身份验证问题。信息可以使用命令行选项进行指定,也可以包含在一个基于 XML 的对象描述文件中。globusrun-ws 命令是同步执行的,因此作业在提交时并不会返回控制权。相反,它会通过显示作业的状态,以交互方式提供一些反馈。基于这些状态信息,您可以选择使用 Ctrl C 来取消某个作业。

作业提交的前提条件

所有的用户都必须通过身份验证并具有有效的证书才可以提交作业。这个作业可能需要将证书委托给他人来执行远程操作,例如分段传输文件。

下面的例子假设已经使用 grid-proxy-init 命令生成了一个有效的代理。然而,证书也可以通过作业请求进行传输,或者上传到 Delegation 服务中。清单 1 是提交一个简单作业(用来获取日期)的例子。-c 选项指定要运行 /bin/date 命令。


清单 1. 提交作业来获取日期
												
																		
[globust@gt4-test ~]$ grid-proxy-init
Your identity: /C=US/O=UTAustin/OU=TACC/CN=Globus User/UID=globust
Enter GRID pass phrase for this identity:
Creating proxy .............................................. Done
Your proxy is valid until: Thu May 19 23:35:47 2005

[globust@gt4-test ~]$ globusrun-ws -submit -c /bin/date
Submitting job...Done.
Job ID: uuid:254e353e-c884-11d9-9304-0011435a15ac
Termination time: 05/20/2005 16:36 GMT
Current job state: Active
Current job state: CleanUp
Current job state: Done
Destroying job...Done.

												
										

作业描述文件

在命令行中指定多个作业参数可能会是一件令人讨厌的事情。当有多个参数与一个作业相关时,可以使用作业描述文件。

作业是使用 -f 选项提交的,后面跟着作业描述文件名。在作业描述文件中可以使用变量。在提交作业时,GRAM 会处理作业描述文件,并替换变量的值。

在下面这个例子中,变量 GLOBUS_USER_HOME 对应我的主目录。这个变量会被替换成解析后的值,这是到主目录的实际路径。在清单 2 中,我们提交了一个使用提交描述文件 simple_test.xml 描述的作业。这个作业使用 echo 命令将输入参数重定向到标准输出上。在这里,我们规定,应该将标准输出重定向到主目录中的 stdout 文件。


清单 2. 使用作业描述文件
												
																		
globust@gt4-test ~]$ globusrun-ws -submit -f simple_test.xml 
Submitting job...Done.
Job ID: uuid:db96c126-c884-11d9-8a94-0011435a15ac
Termination time: 05/20/2005 16:41 GMT
Current job state: Active
Current job state: CleanUp
Current job state: Done
Destroying job...Done.

[globust@gt4-test ~]$ cat simple_test.xml 
<job>
    <executable>/bin/echo</executable>
    <argument>Wow, we're submitting Grid Jobs!</argument>
    <stdout>${GLOBUS_USER_HOME}/stdout</stdout>
    <stderr>${GLOBUS_USER_HOME}/stderr</stderr>
</job>

												
										

批处理模式

除了同步模式之外,globusrun-ws 命令还可以使用批处理模式来提交后台作业。

要使用批处理模式,则需要指定一个文件,其中 GRAM 应该将 Job EPR 保存到所管理的作业资源中,然后在与这个作业相关的一系列命令中指定这个文件。

在这个例子中,我们将提交与上一个例子相同的作业,但是我们使用 -batch 选项指定它应该在后台运行。控制权会立即返回,因此您可以在这个作业运行的同时执行其他工作。后台作业的状态可以使用 globusrun-ws 命令的 -status 参数进行查询,并指定 -job-epr-file,该参数可以确定与这个作业相关的 ManagedJob 对象。


清单 3. 在后台运行清单 2 中的作业
												
																		
globust@gt4-test ~]$ globusrun-ws -submit -batch -f simple_test.xml -o st.epr
Submitting job...Done.
Job ID: uuid:db96c126-c884-11d9-8a94-0011435a15ac
Termination time: 05/20/2005 16:41 GMT
Current job state: Active
Current job state: CleanUp
Current job state: Done
Destroying job...Done.

[globust@gt4-test ~]$ globusrun-ws -status -job-epr-file st.epr
Submitting job...Done.

												
										

作业变量

您可以在作业描述文件中为这个作业设置环境变量,并通过指定一个 count 参数来控制该作业运行的次数。在下面这个例子中,环境变量 CONDOR_CONFIG 已经设置,以指定 condor 配置文件的位置;count 变量说明这个作业应该运行 25 次。


清单 4. 确定一个作业运行多少次
												
																		
    <environment>
        <name>CONDOR_CONFIG</name>
        <value>/usr/local/condor/condor-6.7.7/etc/condor_config</value>
    </environment>

    ...
 
    <count>25</count>

												
										

文件分段传输

作业描述符文件可以包括文件传输指令,它控制输入和输出文件的分段传输。这些指令使用了 Reliable FileTransfer(RFT)语法,在指定源 URL 和目的 URL 时可以支持第三方的文件传输。

RFT 服务是通过 GRAM 调用来分段传输输入文件和输出文件的。RFT 类似于一个 GridFTP 客户端,通过持续进行传输来管理数据的传输和状态信息。它通过支持检查点和为崩溃的文件传输提供重启功能而增强了可靠性。

除了要对输入和输出文件进行分段传输之外,GridFTP 还可以用来在作业执行期间对输出文件进行监视。GridFTP 可以检查输出文件的状态,并传输任何新信息,从而有效地处理输出数据。

清单 5 给出了文件分段传输指令,它用来从一个远程机器 gt4-test1 上获取一个文件,并将其复制到 /tmp/simpleTestFile 中的本地文件系统中。


清单 5. 文件分段传输指令
												
																		
<fileStageIn>
     <transfer>
         <sourceUrl>gsiftp://gt4-test1:2811/tmp/simpleTestFile</sourceUrl>
         <destinationUrl>file:////tmp/simpleTestFile</destinationUrl>
     </transfer>
</fileStageIn>

												
										

除了对文件进行分段传输之外,还可以使用 <fileCleanUp> 指令自动删除文件,如清单 6 所示:


清单 6. 自动清除文件
												
																		
<job>
     <fileCleanUp>
        <deletion>
            <file>file:////tmp/simpleTestFile</file>
        </deletion>
    </fileCleanUp>
</job>

												
										

多作业支持

作业描述 XML 模式支持多作业 的概念,即由多个作业或子作业组成的作业。这种方法可以用来将一组相关的作业绑定在一起,并将其一次提交给 GRAM。

GRAM 使用一个集中地点来对多作业环境中的各个进程进行同步。这用于那些在完成其他计算之前需要在执行过程中的某个特定地方集中的并行作业。

作业描述符文件中的每个子作业都必须为工厂指定一个端点。这允许并行地向多个主机提交作业。

下面这个例子为一个由两个子作业做成的作业使用了一个多作业的描述文件 —— 一个作业用来获取日期,另外一个作业使用 echo 命令将输入参数传递给标准输出。第一个子作业的输出被发送到主目录中的 stdout.p1 文件中,第二个子作业的输出被发送到 stdout.p2 文件中。


清单 7. 两个作业,只花一份钱
												
																		
<?xml version="1.0" encoding="UTF-8"?>
<multiJob xmlns:gram="http://www.globus.org/namespaces/2004/10/gram/job" 
     xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
    <factoryEndpoint>
        <wsa:Address>
            https://localhost:8443/wsrf/services/ManagedJobFactoryService
        </wsa:Address>
        <wsa:ReferenceProperties>
            <gram:ResourceID>Multi</gram:ResourceID>
        </wsa:ReferenceProperties>
    </factoryEndpoint>
    <directory>${GLOBUS_LOCATION}</directory>
    <count>1</count>

    <job>
        <factoryEndpoint>
            <wsa:Address>https://localhost:8443/wsrf/services/ManagedJ
            obFactoryService</wsa:Address>
            <wsa:ReferenceProperties>
                <gram:ResourceID>Fork</gram:ResourceID>
            </wsa:ReferenceProperties>
        </factoryEndpoint>
        <executable>/bin/date</executable>
        <stdout>${GLOBUS_USER_HOME}/stdout.p1</stdout>
        <stderr>${GLOBUS_USER_HOME}/stderr.p1</stderr>
        <count>2</count>
    </job>

    <job>
        <factoryEndpoint>
            <wsa:Address>https://localhost:8443/wsrf/services/ManagedJ
            obFactoryService</wsa:Address>
            <wsa:ReferenceProperties>
                <gram:ResourceID>Fork</gram:ResourceID>
            </wsa:ReferenceProperties>
        </factoryEndpoint>
        <executable>/bin/echo</executable>
        <argument>Hello World!</argument>        
        <stdout>${GLOBUS_USER_HOME}/stdout.p2</stdout>
        <stderr>${GLOBUS_USER_HOME}/stderr.p2</stderr>
        <count>1</count>
    </job>

</multiJob>

												
										







调度器

上面我们简要介绍了网格是如何包含在调度器的控制之下进行操作的集群资源。调度器会对吞吐量进行性能和效率的优化。

GRAM 使用实现 GRAM WS 适配器插件 API 的适配器来对调度器进行协调。这些调度器的安装和配置应该在安装或配置 Globus Toolkit 之前完成。

GRAM 调度器适配器包含在 Globus PBS (Portable Batch System)的发行版、 Condor 和 Platform Load Sharing Facility (LSF)中。 Globus 文档介绍了 PBS 的设置步骤,因此我们下面将介绍一下 Condor 和 Platform LSF。我们假设您已经正确安装并配置了 Globus(这包括导出的环境变量,例如 ANT_HOMEJAVA_HOMEGLOBUS_LOCATION)。在 Globus 的安装目录中,执行下面的命令:

												
														% configure -prefix=$GLOBUS_LOCATION -enable-wsgram-lsf -enable-wsgram-condor
% make
% make install

												
										

假设这个步骤成功完成了,那么在 $GLOBUS_LOCATION/etc 目录中,每个调度器都会有一个 gram-service,如清单 8 所示:


清单 8. 创建一个 gram-service 监听
												
																		
[mausolf@gt4-test etc]$ pwd
/usr/local/globus/globus-4.0.0/etc
 [mausolf@gt4-test etc]$ ls gram-service-*
gram-service-Condor:
jndi-config.xml

gram-service-Lsf:
jndi-config.xml

gram-service-Fork:
jndi-config.xml

gram-service-Multi:
jndi-config.xml

												
										

jobType

在提交作业时,您可以使用 jobType 指令指定使用哪一个调度器。在 jobType 中指定的名称必须与 JNDI 配置文件中这个服务所使用的名称完全匹配。

例如,在下面这个例子中,作业 jndi-config.xml (位于 $GLOBUS_LOCATION/etc/gram-service-condor 目录中)将名称 condor 赋予这个服务。下面这个例子使用了一个作业描述文件 simple2test.xml 将作业提交给 condor


清单 9. 指定使用哪个调度器
												
																		
<?xml version="1.0" encoding="UTF-8"?>
<job>
    <executable>/usr/local/condor/condor-6.7.7/examples/sh_loop</executable>
    <directory>${GLOBUS_USER_HOME}</directory>
    <argument>123</argument>
    <stdin>/dev/null</stdin>
    <stdout>${GLOBUS_USER_HOME}/stdout</stdout>
    <stderr>${GLOBUS_USER_HOME}/stderr</stderr>
    <jobType>condor</jobType>
</job>

												
										

可以在命令行中使用 globusrun-ws 来提交这个作业,如下所示:

												
														[globust@gt4-test ~]$ globusrun-ws -submit -batch -f simple2test.xml -o st2.epr

												
										

在这个例子中,这个作业是在后台运行的。控制权会立即返回,您可以通过提供 job-epr-file 来获得后台作业的状态,如下所示:

												
														[globust@gt4-test ~]$ globusrun-ws -status -job-epr-file st2.epr
Current job state: Done

让我们来看一个更加真实的多作业提交系统,它可以用类似的方式提交作业。因为我们要提交多作业,所以将 jobType 指定为 Condor,然后通过 GRAM 和 Condor 来查询其状态。


清单 10. 为多作业指定调度器
												
																		
 [globust@gt4-test ~]$ globusrun-ws -submit -batch -f multi3test.xml -o mt3.epr
Delegating user credentials...Done.
Submitting job...Done.
Job ID: uuid:b701732a-c95f-11d9-870d-0011435a15ac
Termination time: 05/21/2005 18:48 GMT

 [globust@gt4-test ~]$ condor_q
 Submitter: gt4-test.tacc.utexas.edu : <129.114.50.64:54109> 
 : gt4-test.tacc.utexas.edu
 ID      OWNER            SUBMITTED     RUN_TIME ST PRI SIZE CMD                
 62.0   globust         5/24 11:07   0+00:00:04 R  0   0.0  sh_loop 1100      
 63.0   globust         5/24 11:07   0+00:00:00 R  0   0.0  sh_loop 1200      

2 jobs; 0 idle, 2 running, 0 held


 [globust@gt4-test ~]$ globusrun-ws -status -job-epr-file mt3.epr
Current job state: Pending 

												
										

清单 11 给出了用于清单 10 中的多作业提交的作业描述文件。所指定的可执行文件 sh_loop 是 Condor 发行版中提供的一个示例程序,它会循环一段指定的时间。之所以选择这个例子是因为它非常简单,而且可以指定作业的持续时间,这让我们可以使用 Condor 和 GRAM 工具来展示查询作业的状态。


清单 11. 清单 10 中作业所使用的作业描述符
												
																		
[globust@gt4-test ~]$ cat multi3test.xml 
<?xml version="1.0" encoding="UTF-8"?>
<multiJob xmlns:gram="http://www.globus.org/namespaces/2004/10/gram/job" 
     xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing">
    <factoryEndpoint>
        <wsa:Address>
            https://gt4-test.tacc.utexas.edu:8443/wsrf/services/ManagedJ
            obFactoryService
        </wsa:Address>
        <wsa:ReferenceProperties>
            <gram:ResourceID>Multi</gram:ResourceID>
        </wsa:ReferenceProperties>
    </factoryEndpoint>
    <directory>${GLOBUS_LOCATION}</directory>
    <count>1</count>

    <job>
        <factoryEndpoint>
            <wsa:Address>https://gt4-test.tacc.utexas.edu:8443/wsrf/serv
            ices/ManagedJobFactoryService</wsa:Address>
            <wsa:ReferenceProperties>
                <gram:ResourceID>Condor</gram:ResourceID>
            </wsa:ReferenceProperties>
        </factoryEndpoint>
        <executable>/home/mausolf/sh_loop</executable>
        <argument>1100</argument>        
        <stdout>${GLOBUS_USER_HOME}/stdoutM3.p1</stdout>
        <stderr>${GLOBUS_USER_HOME}/stderrM3.p1</stderr>
        <count>1</count>
    </job>

    <job>
        <factoryEndpoint>
            <wsa:Address>https://gt4-test.tacc.utexas.edu:8443/wsrf/serv
            ices/ManagedJobFactoryService</wsa:Address>
            <wsa:ReferenceProperties>
                <gram:ResourceID>Condor</gram:ResourceID>
            </wsa:ReferenceProperties>
        </factoryEndpoint>
        <executable>/home/mausolf/sh_loop</executable>
        <argument>1200</argument>        
        <stdout>${GLOBUS_USER_HOME}/stdoutM2.p2</stdout>
        <stderr>${GLOBUS_USER_HOME}/stderrM2.p2</stderr>
        <count>1</count>
    </job>

</multiJob>

												
										







结束语

本文对 Globus Toolkit 4.0 进行了简要的介绍,并详细介绍了 GRAM 和支持服务的内容。文中还包括几个网格作业提交的例子,用来提供通过 GRAM 来提交作业和监视作业的经验。在更复杂和实际的环境中,GRAM 还需要作出一个明智的决定,来确定将作业提交到哪一个资源和调度器上。这些信息可以通过 MDS(Monitoring and Discovery Service)获得。

posted @ 2006-04-17 03:53 wsdfsdf 阅读(375) | 评论 (0)编辑 收藏

面向服务的敏捷性:成功的面向服务体系结构 (SOA) 开发的方法,第 1 部分:: SOA 和敏捷方法基础

本文是由两部分组成的系列文章的第 1 部分,阐述了普遍接受的方法学(例如 Scrum、极限编程(Extreme Programming,XP)、Crystal、动态系统开发方法(Dynamic Systems Development Method,DSDM)和主要研究精益软件开发(Lean Software Development,LSD)的其他方法学)内包含的敏捷开发的基本原则。当今,必须提高业务的灵活性和速度,以应对不断变化的客户需求、市场机会和外部竞争对手的威胁。为使这些业务得以成功,可以采用面向服务的体系结构 (SOA) 的开发方法来设计以适应性(对变化和需求做出响应的能力)为目标的 IT 系统。本系列的第 2 部分详细描述了它们用于开发 SOA 的适应性。

引言

面向服务的体系结构 (SOA) 由 Mark Colan 等受人尊敬的思想领袖定义和阐述(请参阅“Service-Oriented Architecture expands the vision of Web services, Part 1”),作为普遍接受的用于设计可适应的、企业级 IT 系统的新兴风格,它已经得到了很大的发展。虽然目标十分明确,但实现目标的方法却并非如此,因为还没有受到广泛接受的 SOA 方法学。不过,在这方面还是进行了一些研究(请参见 SOA 的方法学)的。

负责设计 SOA 的每个人都会面对两个主要挑战:1) 如何设计一个系统来很好地适应业务流程、业务目标和 IT 体系结构,2) 如何构建一个能对将来的变化做出响应的体系结构?第二个挑战与敏捷性相关,通常在敏捷软件开发方法的背景下进行讨论。在本文中,我们将介绍如何将此方法的思想扩展到 SOA 的设计。我们先回顾一些最常见的敏捷开发方法,然后再研究“精益软件开发”(LSD) 的原则。最后,我们讨论在构建 SOA 的过程中对 LSD 的初步分析。







SOA 入门

什么是 SOA?

在构建 IT 体系结构(特别是企业级体系结构)时,我们的目标始终是:支持业务流程并对业务变化做出响应。在最近几年中,出现了一些构建系统体系结构的新方法,这些方法主要围绕功能单元(称为服务)来构建复杂的系统。

最新的理解是,服务包含 4 个主要方面:

  • 提供
  • 使用
  • 说明
  • 中介
Web 服务也对以上这几个方面提供基于系统和标准的支持。因此,Web 服务具有无与伦比的敏捷性这一优点。例如,使用 Web 服务基础设施可以在运行时更改服务提供者,而不影响使用者。

某个系统本身要被称为基于 SOA 的系统,应具备以下特性:

  • 业务流程映射到软件服务;因此,业务可通过软件进行跟踪。
  • 存在一种基础结构,支持上述服务的 4 个不同方面。这样服务级别就具有高度的敏捷性。
  • 服务是监视和管理单元。因此,一个人可以跟踪业务流程的操作属性和问题。

SOA 应用程序

图 1 从应用程序角度展示了企业级 SOA 所包含的元素。业务流程用户界面应用程序服务应用程序 进行部分和完全支持。业务流程中的一个步骤或者通过人工执行,或者得到用户界面应用程序的支持。用户界面应用程序实现了许多宏工作流,而且它们还使用实现业务功能的服务。

服务编排 层,组合服务 是通过编排语言(例如业务流程执行语言(Business Process Execution Language,BPEL))定义的。组合服务的编排通过基本服务 定义其流程和组成。编排层应由支持图形规范的编排工具提供支持,例如 IBM WebSphere® Business Integration Modeler 和 IBM Rational® Application Developer。

基本服务(由服务编排层使用,也由用户界面应用程序使用)通过服务应用程序实现。而服务实现又可以调用其他服务,这些服务通常来自另外的服务应用程序。


图 1. SOA 的元素
SOA elements






SOA 的方法学

构建一个合理的 SOA 应采用何种开发方法?从前面的部分可以看出,有业务流程、应用程序和服务。显然,对服务建模是此类方法必须支持的主要任务。另一个重要的方面是确保业务流程和服务之间的链接(请参见什么是 SOA)。

文章“Elements of Service-Oriented Analysis and Design”说明了现有的模型(例如面向对象的分析和设计(Object-Oriented Analysis and Design,OOAD)、企业体系结构框架和业务流程建模技术)对 SOA 设计的作用。本文还指出,您需要将其他方法元素用于 SOA,例如用于服务标识和聚合的方法和技术、业务跟踪能力、现有资产的集成和重用。

在另一篇 IBM developerWorks 文章“Service-oriented modeling and architecture”中描述了一种方法,回答了上述许多问题。本文主要介绍服务的建模,它是在域分解、现有系统分析和目标服务建模之类的技术支持下实现的。

引用的这两篇文章提出了许多问题,我们仍需要回答这些问题——例如,SOA 控制问题。我们要提出的另一个问题是:在 SOA 开发中应采用哪些规则和实践来确保服务模型能对将来的变化做出响应?在这里,我们可以求助于各种敏捷软件开发方法。







敏捷软件开发

敏捷软件开发是自上世纪 90 年代 Kent Beck 提出极限编程 (XP) 时开始兴起的,这种编程方法用一组价值标准、原则和实践来规划、编码、设计和测试软件。(有关对 XP 的介绍,请参见 Extreme Programming: A gentle introduction。)

所有敏捷软件开发方法都具有以下几个共同价值标准,例如

  • 频繁检查和改写
  • 频繁交付
  • 协作和密切沟通
  • 深思熟虑的改进
  • 突出需求(递增)、技术和团队能力
  • 授权和自我组织
  • 基于事实而非假象进行处理
  • 勇气和尊重

从这些价值标准可以看出,现在使用的各种敏捷方法都注重不同的实践。

2001 年 2 月定义了 Agile Manifesto,它在流程和工具的基础上评价个体和交互操作,在综合性文档的基础上使用软件,在合共协商的基础上进行客户合作,并在遵循计划的基础上对变更做出响应。它是现今使用的所有敏捷方法的基础。

为了使本文的阐述更加清楚,我们简要介绍了最常用的敏捷方法,因为在开发 SOA 时它们中的许多都是非常有用的。我们知道,SOA 不仅与软件开发有关,而且还与业务和 IT 体系结构有关。因此,如果我们了解软件开发实践,则我们必须始终评估它们是否适合 SOA。在本系列文章的第 2 部分中完成此评估。

Scrum

Scrum 似乎是很简单的,但仍有一些实践会对工作体验产生深远的影响,并获得重要的适应性和敏捷性。在这些方法中,Scrum 与众不同的特点是对自我指导团队、每日团队评估和避免说明性流程进行了极大的提升。Scrum 的一些关键实践包括:

  • 自我指导和自我组织团队
  • 每日就特殊问题(您做了什么、您将做什么和您遇到哪些问题)开站立会议
  • 通常采用 30 天的日历循环
  • 在每个循环的开始,制订客户驱动的适应计划
  • 向参与者演示功能(在每个循环结束时)

对于企业级活动,了解和管理项目间的依赖项非常重要。在 Scrum 中使用“Global Backlog”就可以很好地做到这一点,Global Backlog 是对用户有价值的功能和非功能需求的企业视图。Global Backlog 在全局区分优先级。每个项目从 Global Backlog 获得项目范围内的最重要的部分。“Scrum of Scrums”还涉及项目间的同步,这是一个每两天(或每周)一次的会议,来自每个团队的代表参加这个会议,以便在团队之间同步。

XP

XP(http://www.extremeprogramming.org 和 http://www.xprogramming.com)注重协作、快速和早期软件创建以及有技巧的开发实践。它由一组主要实践(坐在一起、整个团队、信息工作空间、成对编程、每周循环、放松、10 分钟构建、持续集成、测试优先编程、增量设计等等)和一组与之对应的实践(实际客户参与、增量和每日部署、根源分析、共享代码、单独的代码库、协商的范围合同、根据使用情况计费等)组成。

Crystal

Crystal 是具有以下共同特征的一系列方法学:注重频繁交付、密切沟通和深思熟虑的改进。Crystal 的这些特征包括:

Crystal 系列通用优先级可以保证项目的最终成果,提高开发效率,并且符合常规习惯(换句话说,开发人员可以接受它们)。项目团队可以采用 7 个安全特性(前 3 个是 Crystal 的核心,而其余的可以按任何顺序添加,以增加安全性):

  • 频繁交付
  • 深思熟虑的改进
  • 密切沟通;个人安全(信任的第一步)
  • 聚焦
  • 易于访问专家用户
  • 带自动测试的技术环境
  • 配置管理
  • 频繁集成

动态系统开发方法

动态系统开发方法 (DSDM) 提供了一个用于构建和维护系统的控件框架,该框架满足紧急时间限制的要求,而且是成功进行可重复快速应用程序开发 (RAD) 的一剂药方。该方法不仅涉及开发人员对 RAD 的看法,而且还涉及对有效系统开发感兴趣的所有其他相关各方(包括用户、项目经理和质量保证人员)对 RAD 的看法。下面列出了 DSDM 的控制原则:

  • 活动用户必须参与。
  • 必须授权 DSDM 团队进行决策。
  • 注重频繁交付产品。
  • 判断产品是否可接受的一个基本标准是要符合业务目的。
  • 对准确的业务解决方案需要采用循环和增量开发。
  • 开发期间的所有更改都是可逆的。
  • 基本要求是高层次的并区分优先级(以在低优先级的项目上获得一定的灵活性)。
  • 在整个生命周期集成测试。
  • 在所有参与者之间采用协作和合作方法是一项基本要求。







精益生产

制造业已经意识到存在两种生产问题——“可预测的生产”和“新产品开发”。前者的特征是确保具有提前了解需求的能力,因而可以制订确定性计划。后者的特征是没有事先明确了解需求的能力,因而需要随项目的进展不断地调整适应和重新评估。

Craig Larman 在他所著的 Agile and Iterative Development一书中对这些问题做了比较,得出以下结论:

表 1. 可预测的生产和新产品开发的比较

可预测的生产新产品开发
可以首先完成规范,然后再构建。几乎不可能创建提前的、不变的和详细的规范。
在即将开始时,可以可靠地评估所投入的精力和成本。在即将开始时这是不可能的。随着经验数据的不断出现,进行计划和评估的可能性越来越大。
可以对所有详细活动进行标识、定义、安排和排序。在即将开始时这是不可能的。需要采用通过构建反馈循环驱动的适应性步骤。
适应不可预测的变更不是标准要求,而且变更速度相对较慢。创造性地适应不可预测的变更是标准要求。变更速度较快。

例如,Toyota 在上世纪 80 年代使用“精益生产”方法对其汽车工业进行大规模改革,目的是消除浪费,精简价值链(甚至跨所有企业),按需求生产(实时生产),并注重增值人员。







LSD

Mary 和 Tom Poppendieck 已将这些原则和实践从生产环境转用到开发环境(有关详细信息,请参见他们的网站),目标是在整个持续改进期间确定和消除浪费,并减少缺陷和循环时间,而同时稳定地增加商业价值。LSD 的基础就在于诸如 Toyota、Dell 和 Wal-Mart 这些组织所采用的一组“精益生产”标准。

需要注意的重要一点是,像 XP、DSDM、SCRUM 等其他方法一样,LSD 在本质上并不是一种开发方法,而是提供许多应该应用于改进软件开发的基本原则,不考虑使用的开发方法和项目方法。本文的其余部分将快速回顾 LSD 的七个原则和一些工具(例如,下文中用斜体列出的思想)。

原则 1:消除浪费

消除浪费是最基本的精益原则。它是所有其他原则应遵循的原则。实现精益开发的第一步是了解浪费(没有提高代码质量,没有减少生产代码所需的时间和精力,或没有向顾客提供商业价值的任何东西)。第二步是公开最大的浪费源并消除它们。大量研究表明,在早期规范定义的功能中,最多有 45% 的功能在解决方案完成和交付后从未使用过。

原则 2:加强学习

在组织面对软件开发挑战时,往往在组织中安排一个用纪律强加约束的流程,这个流程有更严格的顺序关系。控制理论指出,这种做法会使情况变得更糟。当问题出现时,要做的第一件事是确保反馈循环都各司其职。要做的第二件事是在问题领域增加反馈循环的频率,因为短反馈循环将增强控制能力。

只要有几个人正在做同一件事,就需要进行“同步”。对同步的要求是任何复杂开发流程的基础。“循环”是同步的关键点(团队和客户将了解完成的任务)并强制做出决策。

原则 3:尽可能推迟做出决定

在开发开始前确定需求是防止出现严重问题的一种通常的做法。顺序开发(例如瀑布开发模式)的问题是,它强制设计人员采用深度优先而非广度优先方法。最容易犯大错误的方式是深入研究细节的速度太快。

对于并行开发(例如,所有工作都在循环——即分析、设计、编程和测试——中完成),只要高级概念设计一确定,您就开始对具有最高价值的功能进行编程,甚至此时详细需求还在调查之中。这种探索性方法允许尝试各种选择,然后即可确定限制实现较不重要功能的做法(“选择思考”)。但并行开发要求开发人员在领域内具有足够的专门知识(以预期新兴设计可能的发展方向),并与客户和分析人员(他们设计系统如何解决现有的业务问题)进行密切合作。

原则 4. 尽快交付

客户喜欢快速交付,这常常转化为业务灵活性的提高。对软件开发而言,快速交付是一种选择友好的方法。它允许您暂时不做出选择,直到您减少了不确定性,然后可以做出更明智的基于事实的决策。

所有人都必须始终明白,她或他应如何做才能对业务做出最有效的贡献。您可以告诉他们要做什么(“命令和控制”),也可以搭建一个舞台,让他们自己发挥(“自我组织”)。在快速变化的环境中,只有第二种选择行得通。为了有效地进行自组织,必须开发本地通信和委托方法(例如使用信息发射器)以拉系统 的方式协调工作。在具有适度可变性的复杂环境中,没有任何计划可以做出有效的细粒度工作分配。提早创建详细计划意味着将您的一些决定刻到石头上。进行计划和预期绝非坏事,但要避免根据推测做出不可更改的决定。

快速开发的好处通常大于您的预期。为下几年推出的某种新产品创建简单的经济模型(基本上为损益表 (P&L)),并使用该经济模型推动开发决策。根据市场情况很好地评估哪些延迟将对销售量(例如,早期的高定价损失)和市场份额(例如,市场份额的长期损失)产生影响。该模型将显示在收入和市场份额之间哪种差异将对收益产生影响。

原则 5:向团队授权

通常,改进计划其实并未改变完成工作的方式。这些计划增加了导致工作满意度下降的因素(策略、监督和管理)而没有增加导致工作满意度提高的因素(成绩、认同和责任)。精益思想利用一线工人的聪明才智,相信他们是有能力决定和继续改进其工作方式的人。要是没有遵守纪律、受到激励的人员,软件开发就不能成功,而实验和反馈往往比一次将事情做成更有效。

原则 6:构建完整性

一个产品如果它的各个组件互相匹配并协调工作得很好,则这个产品就具有概念上的完整性;体系结构将在下列各项之间获得有效的平衡:

  • 灵活性
  • 可维护性
  • 有效性
  • 响应能力
要获得概念上的完整性,请降低控制机制的重要性,这有利于:
  • 面对面讨论
  • 小批量
  • 速度
  • 流程

不是从一开始就尝试预测将来的趋势,而是采用宽度优先的方法并保证基本要素正确。然后,让细节浮现出来并对定期重构制订计划,以让体系结构保持健康状态。重构意味着在检测到“异味”时停止工作(例如停止添加新功能),然后在继续开发前,花时间查找和修复问题的根源。

重构只能在测试具有严格的安全保证时才能进行。测试应尽可能自动完成,并作为每日构建和持续构建的一部分运行。请在系统的整个生命周期维护一组综合性测试。这样,系统即可在其有用的生命周期中安全地进行修复和重构。如果没有足够的时间来进行测试,则首先要重新分配在需求文档中编写客户测试所投入的精力。

原则 7:眼观全局

系统越复杂,就越倾向于将系统分为几部分并在本地管理这些部分。本地管理倾向于创建本地性能度量。这些本地度量经常产生导致整体性能降低的系统级结果(局部优化)。虽然 Lance Armstrong 赢得 1999 到 2005 的环法自行车赛的冠军,但他只赢得几次每日登台领奖的机会。就像环法自行车赛,优化每个任务通常是一个很糟糕的策略。

通过知识工作 (knowledge work),很难度量每件事情是否重要,特别是在每次努力都是唯一性和不确定性占优势时。如果您不能度量每件事情的重要性,则部分度量就很有可能转为本地管理。如果您不能度量优化整体业务目标所需的每件事情,则在没有采用局部优化度量的情况下,最好停止度量。

从项目经理的角度看,在管理项目时,可以调整 4 个变量:时间、成本、质量和范围。在这 4 个变量中,可以修改时间、成本和质量——但范围除外。对功能区分优先级,但不在合同中指定要交付的固定功能集合。从固定范围移到可协商范围的方法:先交付高优先级功能,这样就可以早在完全满足客户的一系列期望前交付具有商业价值的大部分产品。







敏捷体系结构

不预先进行任何宏大设计

软件开发方法采用不同的方法来开发项目的体系结构:Rational Unified Process (RUP) 解决了早期的体系结构风险问题(“如果您没有主动解决风险,则这些风险将会伤及您”),而 XP 要求“不预先进行任何宏大设计”。Scrum 只预先定义足够用的体系结构,但之后以增量的方式交付体系结构——区分优先级的方式与其余的功能相同。

从敏捷的角度看,以下这些做法是不明智的:在项目开始时了解所有需求,分析这些需求,然后为整个系统开发体系结构,就像在瀑布模型中一样。重要的是要平衡早期体系结构稳定性和更改的实现之间的需求。当然,一次又一次地修改重要的体系结构成本非常高。另一方面,如果决策很糟糕且不适合已变化的需求,则越早而非越迟改变决策就越好。

确认而非验证

不论您在开发体系结构时使用何种方法 (approach),都需要根据用户的期望(而不根据需求)确认体系结构。这种确认只能通过开发部分解决方案(“骨架”、“衍生应用程序”和“曳光弹”)来演示体系结构是可行的。然后,逐步用细节充实体系结构骨架。

何时开展体系结构工作

传统上,在早期项目阶段,体系结构工作进展到何种程度是由开发团队来决定的。某些敏捷开发方法(例如 XP 和 Scrum)将功能需求和非功能需求放在公共 backlog 中,然后让客户优先选择需求。在客户根据商业价值和关键程度对需求进行优先选择后,开发团队评估投入的精力和成本,然后引入可能带来体系结构风险的专门知识。因此,体系结构是随着需求而逐步开发完成的。

最近,有关何时开展体系结构工作的决定已进行合理处理,该决定不仅是技术决定,而且也是商业和财务决定。增量基金方法将需求细分成最小可市场化功能( Minimum Marketable Features,MMF),并将体系结构细分为体系结构元素(Architecture Elements,AE)。基于启发式方法,MMF 和 AE 按次序来优化各个财务目标(例如最大程度增加 ROI、最大程度减少现金投入、获得较早的回报等)。客户可以了解和评估各个体系结构选项及其财务负担。开发团队将了解提前开发所有体系结构和逐步交付体系结构的财务因素。

传统方法和早期的敏捷方法都是一种“贪婪的方法”:传统方法先“攻击”最具风险的部分,而早期的敏捷方法先“攻击”最有价值的部分。IFM 允许客户和开发团队选择最有益的方法。

服务的持续重构

在 SOA 上下文中,一个应用程序决不会作为单独的应用程序出现。就像我们在 SOA 应用程序中所讲述的那样,服务应用程序有多种用户,因而存在各种应用程序之间的依赖关系,这一点作为服务模型中的服务依赖性清楚描述过。任何服务都应被考虑是否有可能被其他应用程序重用。因此,服务应用程序必须被认为是可重用的产品。实际上,这意味着敏捷性无可置疑地变得更重要了,因为应用程序使用者的数量增加了。这些使用者不仅有最终用户,而且也有成为应用程序的使用者/客户的其他应用程序。随着客户数量的增加,更改的数量当然也会增加,因为并非所有的用户都有预见能力。

在驱动敏捷开发的 SOA 中存在一个中心因素:服务模型,即服务、服务的依赖性、组织和流程的模型。在第一个订单交付后,服务模型就随着时间及服务接口的定义而发展。公司将认识到其服务模型的当前版本具有弱点,因为没有采用正确的方法定义服务的责任。它们不得不将责任从一个服务(或服务的一个版本)移到另一个服务,并更改服务接口。服务模型的重构是无法避免的,并且在敏捷软件开发中,我们鼓励进行持续重构。

重构服务意味着通过将责任从一个服务转移到另一个服务来更改接口。这可以使用服务模型有控制地完成。服务模型成为 SOA 中进行敏捷开发的基本工具,因为没有该工具,就很难控制服务重构。因为我们采用了服务模型,我们准备将敏捷软件开发扩展到 SOA 级别!

从敏捷 SOA 前沿传来一个好消息:敏捷性还变得较容易管理了。通过更改组合服务的服务编排,您可以捕获业务流程中的更改。编排中的更改比基本服务实现中的更改更简单。







结束语

在这个由两部分组成系列文章的第 1 部分,我们介绍了 SOA 的概念、敏捷软件开发和 LSD,并尝试概述敏捷或精益原则和实践对体系结构(包括服务体系结构)的影响。

本系列的第 2 部分尝试将每种精益软件原则与 SOA 开发混合起来。这种混合与文章的第 1 部分“敏捷开发”一章一起,构成了敏捷 SOA 开发的基础。

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

面向服务的敏捷:成功的面向服务的体系结构 (SOA) 开发的方法,第 2 部分: 如何使油和水相溶

本文探讨了各种方法,例如 Scrum、极限编程(Extreme Programming,XP)、Crystal、动态系统开发方法(Dynamic Systems Development Method,DSDM)等等,它们专注于精益软件开发(Lean Software Development,LSD)的概念。在这个由两部分组成的关于敏捷软件开发的系列中,作者详细地评估了它们对于开发面向服务的体系结构(Service-Oriented Architecture,SOA)的适宜性。

引言

正如我们在本系列的第 1 部分中所阐释的,面向服务的体系结构 (SOA) 和敏捷开发两个概念都旨在用于可适应的企业 IT 系统。然而,在关于 SOA 开发和敏捷方法的主题的 CBDI 说明中提到,敏捷开发和 SOA,就如同油和水一样,不能溶合在一起。所以,如果头脑中已经有了这样的想法,您还真的可以像 SOA 那样来将敏捷开发原则扩展到多应用程序环境中吗?在本系列的这一部分中,我们提供了证据来证明答案是“肯定的”。







SOA 和精益软件开发:Fit-Gap 分析

通过依次介绍每个精益软件开发原则,我们研究如何使用它们来使 SOA 的开发从中受益。除此之外,我们还讨论了它们在使用敏捷方法的环境中的好处。下表给出了 LSD 原则与其在敏捷方法的环境中带给 SOA 开发和交付的基本好处之间的初始高级映射。


表 1. LSD 与 SOA 原则的初始映射
LSD 原则 SOA 的好处
1. 消除浪费
  1. 宽度优先的服务模型开发有助于识别正确的服务候选者和重用能力。
  2. 值流映射 (Value stream mapping),一种用于系统地检测没有价值的处理步骤的技术,使您能够识别有价值的服务。
2. 加强学习
  1. 反馈有助于定义重用的服务。
  2. 同步在服务的实现阶段特别有用。
3. 尽可能晚地决定 不确定服务接口的细节使得有可能通过实践来学习。
4. 尽可能快地交付
  1. 使用服务的情节串连图板 (Storyboard) 和“SRC 卡片”(服务 (Service)、责任 (Responsibility)、协作 (Collaboration))来创建更小的工作单元和更高的吞吐量。
  2. 创建约定的一个简单的经济模型,可以用于驱动开发决策。
5. 向团队授权 通过授权和委托微观设计决策给负责交付 SOA 中的服务的专业人员,您增加了交付服务的能力,该服务满足当前的业务需求,而不是先前预测的或者规定的业务需求。
6. 构建完整性
  1. 通过简化端到端的通信流程,确保业务流程和交付的 IT 服务之间具有更强的耦合性以及期望的服务质量(Quality of Service,QoS)。这种方法使开发人员能够确保交付的服务具有所需的完整性。
  2. 通过解构代码和体系结构,确保开发和部署的服务能够交付所期望的 QoS,同时支持业务环境的持续改变。使用这种服务模型使受控解构成为可能。
7. 眼观全局 就其真实的本质来说,SOA 专注于业务流程联合,重点在于企业。通过确保工作团队坚持把工作重心放在全局性的问题上(眼观全局),您实现了用于确保服务验证和编排与核心业务流程紧密配合的最佳实践。

让我们进一步详细地讨论上面的表 1 中定义的映射:







原则 1:消除浪费

宽度优先服务模型开发

为了理解什么是重要的以及什么是多余的,使用宽度优先 (breadth-first) 取代深度优先 (depth-first) 是明智的,先取得总体认识,然后再深入细节。当开发企业级 SOA 时,您应该避免以遗漏关键部分为代价来预先构建系统无关紧要的部分的详细分析文档目录。当然,很难预知未来和灵活性的需求;因此,快速反馈是必要的。

一些来自面向服务的建模和体系结构方法(Service-Oriented Modeling and Architecture Method,SOMA)的技术很好地支持“宽度优先”方法,即:自顶向下 (top-down) 域分解、自底向上 (bottom-up) 现有系统分析以及目标-服务建模(请参阅文章“Service-oriented modeling and architecture”)。在经过总体观察以后,决定在服务组合 (Service Portfolio) 中包含哪些服务。只有到这个时候,您才能详细地定义服务。

值流映射

映射值流是开始发现流程中的浪费的一种好方法。它把重点放在用户的产品及其价值上,而不是组织、资产、技术、流程和人员上。利用值流映射的结果,您可以将精力投入到给组织带来最多价值的流程和服务上。挑选最大的机会去增加流动和增值时间 (value-added time)。您可以利用这项技术来分析业务流程(将由 SOA 支持)或者软件开发流程(用于开发 SOA)。







原则 2:加强学习

反馈

服务的“用户”是应用程序。预先设计一个用于所有应用程序的最佳重用的服务接口是不可能的。实际上,您是从初始的接口和演示程序开始,然后部署服务,最后从使用的应用程序获得反馈。一个小先遣队开发了一个简单跨系统的试验应用程序:

  • 采用一个业务流程
  • 分析和设计它的服务
  • 原型化用户接口
  • 与后端集成
  • 跨整个流程

如果可能,试验应用程序应该变成产品。当这种跨系统的应用程序在生产中得到证实时,您就知道了您有了可工作的应用程序。到了那时,多个小组就可以使用一样的方法并且每次进行多项工作。

与采用瀑布方式开发整个 SOA 相比,依赖于快速交付和频繁反馈甚至更为重要,这是因为您不可能第一次就做出正确的设计。敏捷方法推动了快速反馈和热点 (Hot Spot) 的出现,这里需要灵活性。工程实践(例如测试优先开发和持续集成)减少了开发人员获得反馈的时间。增量功能的频繁交付支持来自客户或用户的直接反馈。

同步

敏捷方法至少使项目间的依赖关系可见,并且还有一些处理它们的工具(请参阅本系列第 1 部分中的 Scrum 部分)。项目间频繁同步的想法在服务的实现阶段特别有用,这里可能发生服务范围内的改变,因为正是在这一阶段详细地分析服务。







原则 3:尽可能晚地决定

不确定服务接口的细节

在像 SOA 这样企业级的约定中,似乎最好是在非常详细的层次上设计服务接口,让不同的项目来实现它们。这种方法的优点好像是服务应用程序可以独自工作,而不需要长期地与其他项目同步。遗憾的是,这并不能正常工作,因为您无法预先确定所有的细节。面对不确定性,这样做的结果就是导致浪费(以错误的细节的方式)。长期进行来实现错误细节的项目将难以使它们的代码解构变得简单。这会产生一个未达到最佳状态、却又固定的服务模型。

尽可能晚地决定意味着,在有证据可以清楚地判断服务应该是什么样子之前,不确定服务接口的细节,而不是假装无所不知。这就促使开发小组与公司的其他部门经常性地保持步调一致,而且它还产生更好的服务模型。







原则 4:尽可能快地交付

拉系统

敏捷开发中的拉系统 (Pull System) 借助于信息发射源 (Information Radiator) 使人们能够自己确定去做什么(例如,走廊上可能有一个白板,所有相关的用户素材都写在上面的卡片上;分配工作意味着将素材卡片 (Story Card) 从白板的“to-do”区移到“checked-out”区)。

在 SOA 环境中,您可以在卡片上编写用户素材和服务。通过添加服务,工作单元甚至变得更小,因为正如本系列的第 1 部分SOA Application 部分中所述,功能性是在用户界面应用程序、服务编排以及服务应用程序之间分配的。排队论指出,更小的工作包产生更高的吞吐量,例如功能的更快交付。

众所周知的用于面向对象 (OO) 设计的 CRC 卡片(类 (Class)、责任 (Responsibility)、协作 (Collaboration))技术(请参阅 A Laboratory for Teaching Object-Oriented Thinking 以获得背景信息)可以修改成 SOA 设计中的 SRC 卡片。“面向服务的分析与设计原理”包括这种技术的初始示例。

约定的经济模型

传统上,软件开发有时被看作是产生成本。近来,软件开发被看作是产生收入,可以帮助利用经济期权。基于期权的软件经济从金融市场提取出相似之处:交付运行的软件的短期迭代被看作是实物期权 (Real Option)。就像金融期权 (Financial Option) 一样,实物期权通过现在非常少量的投资,来向您提供可能从未知的将来获得收益的机会。

但是并不需要走那么远:如果您创建约定的简单经济模型并使用它来驱动开发决策,甚至 SOA 约定也将从中受益。有了这个经济模型,就可以向团队成员授权,让他们自己明确什么对于业务是重要的:他们可以都从相同的假定开始工作。如果您考虑减少一些特性,销售部门可能推测出,没有这些特性,他们将少销售百分之“X”单位的产品。







原则 5:向团队授权

对于任何软件开发,最有资格作决定的人就是在第一线工作的人。在解决方案体系结构层次上仍然需要严格的控制,而基础服务开发应该尽可能地灵活。通过授权给最接近实现的专业人员去做微观决策,您可以确保服务的最终代码满足所需要的功能性。在企业 SOA 中,您可以从授权和委托设计决策给服务的开发人员(在定义的范围内)中受益。

无论何时沿着层次结构向下委派决策权,您都必须确保所有的决策者都理解了统帅全局的愿景。通常,决策应该始终的是大家共同参与的活动,而不是孤立的活动。跨功能团队的环境(出现在敏捷项目中)促进了决策协作。







原则 6:构建完整性

构建在概念上具有高度完整性的 SOA 的方法是从客户到开发团队、以及开发团队的上游流程和下游流程之间都有良好的信息流。从我们的角度来看,我们认为这一原则在服务开发层次以及服务编排中具有很高的价值。通过维持业务和 IT 专业人员之间良好的通信水平,可以确信您所交付的 IT 解决方案满足当前以及未来的业务流程和需求。随着结构良好的 SOA 中的业务和 IT 之间的联系越来越紧密,逐渐要求所交付的服务能够满足和紧密配合超出目标的业务流程。如果没有这种高层次的完整性,那么交付的服务不满足必要的业务要求或 QoS 的风险将会增加。

解构

现在,在 IT 产业中解构开发代码的实践得到认可已经有一段时间了。在 SOA 的环境中,这种实践同样重要。由于与业务的配合越来越紧密,以及需要确保所交付的服务可以支持不断变化且敏捷的业务环境,因此需要从本质上确保持续地评审和解构基础服务的设计。如果不能做到这一点,就将导致服务僵硬、不灵活,这对支持不断变化的业务环境没有益处。正如本系列的第 1 部分中的 Agile architecture 部分所述,该服务模型是控制持续解构的出色工具。







原则 7:眼观全局

SOA 的一项基本原则就是企业层次上的业务联合。对于任何企业体系结构 (Enterprise Architecture) 约定,都存在一个内在的需求,即确保始终维护统帅全局的“城市规划 (city planning)”视图,并专注于将在 SOA 中部署的单个服务的详细设计。如果陷入以牺牲整体为代价来换取最佳的单个部分(或者服务)的诱惑中,您将承受交付不灵活的 SOA 的风险,它与企业中的关键业务流程是不相配的。







结束语和展望

正如我们在本系列中展示的,SOA 可以从敏捷软件实践和 LSD 的已证明有效的原则中获得极大的好处。敏捷和 SOA 这两种实践的匹配基于一个共性——两者都极力设法处理变化。服务接口应该当作实现可能将改变的应用程序的必要条件。敏捷项目为要求它们实现的服务接口的改变做好了准备。

SOA 的“持续的”解构意味着经常更改服务接口和服务组合。SOA 中的这种敏捷需要实现项目中的敏捷。基于本文中所强调的要点,我们要说,当实现项目采用敏捷方法并接受改变时,SOA 中真正的敏捷将起作用。

通常油和水并不能溶合在一起。不可否认,极限编程的想法和以可控的方式建立企业级服务体系结构之间存在着文化差异。但这仅仅是初步估计,在写完本文之后,我们可以声明存在一种乳化剂,即 LSD 的原则。

所以,最后我们将声明,在 SOA 和 LSD 原则的上下文中,“油和水确实可以溶合”!

posted @ 2006-04-17 03:50 wsdfsdf 阅读(172) | 评论 (0)编辑 收藏

用于实现 Web 服务的 SOA 编程模型,第 4 部分: IBM 企业服务总线介绍

企业服务总线(Enterprise Service Bus,ESB)体系结构模式支持在面向服务的体系结构 (SOA) 中虚拟化服务交互并对其进行管理。它使得交互可以在服务提供者和服务请求者之间进行,并且可以使用各种中间件技术和编程模型加以实现。它对本系列的前一篇文章中介绍的 SOA 编程模型进行了扩展。

引言

SOA 提供了一种灵活的、可扩展且可组合的方法来重用和扩展现有应用程序以及构造新的应用程序。服务声明它们实现的或期望其他服务实现的接口,并且声明控制潜在伙伴交互的策略,从而公布各种功能(包括提供的和请求的)。Web 服务描述语言(Web Services Description Language,WSDL)和其他 Web 服务标准(如 WS-Policy)提供了用于这些声明的词汇。(请参阅参考资料,以获得指向 WSDL Version 2.0 Part 0: Primer 的链接。)

业务功能的虚拟化(SOA 的一个主要目标)是通过将服务的定义和使用与服务的实现分离开来而实现的。我们可以使用各种技术实现服务,这些技术包括 IBM WebSphere® MQ、IBM CICS® 或 IBM IMS™、Java™ 2 Platform Enterprise Edition (J2EE) Enterprise JavaBeans (EJB)、Java 类、IBM DB2® 查询、Java 消息服务 (JMS) 或 Microsoft® .NET。服务请求者将请求发送到提供其所需功能的服务提供者,而不必考虑它如何实现。

ESB 是一种体系结构模式,支持虚拟化通信参与方之间的服务交互并对其进行管理。它提供服务提供者和请求者之间的连接,即使它们并非完全匹配,也能够使它们进行交互。此模式可以使用各种中间件技术和编程模型实现。

本文将定义 ESB 模式和它在 SOA 内的角色。后续文章将详细描述其使用场景、使用目前的技术实现 ESB 模式的方法,以及 ESB 技术未来的发展方向。







什么是 ESB?

在 ESB 模式中,服务交互的参与方并不直接交互,而是通过一个总线交互,该总线提供虚拟化和管理功能来实现和扩展 SOA 的核心定义。IBM ESB 模式提供以下几方面的虚拟化:

  • 位置和标识:参与方不需要知道其他参与方的位置或标识。例如,请求者不需要知道请求是否可以由某个提供者提供服务。您可以随意添加或删除服务提供者,而不会带来任何干扰。
  • 交互协议:参与方不需要采用相同的通信协议或交互方式。表达为 SOAP/HTTP 的请求可能由仅理解 Java 远程方法调用 (RMI) 的提供者提供服务。
  • 接口:请求者和提供者不需要就公共接口达成协议。ESB 可以通过将请求消息转换为提供者所期望的格式来处理此类差异。
  • (交互)服务质量 (QoS):参与方声明其 QoS 要求,包括性能和可靠性、请求的授权、消息内容的加密/解密、服务交互的自动审核以及如何对请求进行路由(如根据工作负载分布标准将请求路由到可用的实现)。描述请求者和提供者的 QoS 要求和功能的策略可以由服务自己实现或者由进行不匹配补偿的 ESB 实现。

因此 ESB 模式使请求者不用了解服务提供者的物理实现——从应用程序开发人员和部署人员的角度来看均是如此。总线负责将请求交付给提供所需功能和 QoS 的服务提供者。提供者接收他们要响应的请求,而不知道消息的来源。ESB 本身对使用它的服务请求者和提供者均不可见。应用程序逻辑可以使用各种编程模型和技术调用或交付服务,而无需考虑是直接连接还是通过 ESB 传递的。连接到 ESB 是部署决策;应用程序源代码不会受到影响。

ESB 支持许多交互类型,包括单向、请求/响应、异步、同步和发布/订阅。它还支持复杂事件处理(在复杂事件处理中,可能会观测到一系列事件),以产生一个事件作为该系列中的关系的结果。

图 1 对基本 ESB 模式进行了描述。消息流过将各个通信参与方相互连接在一起的总线。某些参与方会调用其他参与方提供的服务;而其他参与方则会向感兴趣的使用者发布信息。端点与 ESB 交互的位置称为服务交互点 (SIP)。例如,SIP 可以是 Web 服务端点、WebSphere MQ 队列或 RMI 远程对象的代理。服务注册表将捕获描述以下内容的元数据:SIP 的要求和功能(例如,提供或需要的接口)、它们希望与其他 SIP 的交互方式(例如,同步或异步,通过 HTTP 或 JMS)、它们的 QoS 要求(例如,首选的安全、可靠交互)以及支持与其他 SIP 交互的其他信息(例如,语义注释)。


图 1. 基本 ESB 模式
基本 ESB 模式

将总线插入参与方之间,提供了将它们的交互通过称为中介 的构造进行协调的机会。中介对请求者和提供者之间动态传递的消息进行操作。对于复杂的交互,可以按顺序将中介连在一起。中介模式部分讨论了实现这些虚拟化、QoS 和管理概念的常用中介模式。

ESB 模式为 SOA 实现提供了灵活且易于管理的方法。总线透明地插入端点之间,可以提高服务质量,可以促进请求者和提供者间的交互(而不受协议、交互模式或服务功能不匹配的影响),还可以支持监视和管理。







SOA 用户角色及其任务

通过研究创建和管理 SOA 解决方案的用户的角色及任务,可以进一步深入了解 ESB 模式。ESB 工具和运行时将 SOA 解决方案的生命周期划分为四个阶段:

  • 发现与描述:对可以在整个 ESB 中进行互连的 SIP 进行标识和描述。这包括创建新的服务、发现现有服务、以及描述其接口、要求和功能。
  • 建模与构建:通过新建的或现有的中介进行 SIP 互连,以描述解决方案的端到端交互。
  • 配置与部署:针对特定的运行时拓扑配置解决方案的抽象声明,并对其进行部署,同时创建必要的运行时构件。
  • 监视与管理:通过 SIP 和中介的行为监视和管理解决方案。此阶段将使用 ESB 运行时中的检测和控制点、以及观测和响应消息流的中介。

对于 ESB 中间件,最重要的 SOA 解决方案开发角色是集成开发人员和解决方案管理员,但其中也涉及到业务分析人员、解决方案架构师、实现人员、适配器开发人员和操作人员。(这些角色都是概念性的;一个人可以担任其中的多个角色。)图 2 显示了这些角色交互的方式。

业务分析人员确定业务需求,并检查业务流程。他们将概括出解决方案的目标、涉及的业务流程、监视解决方案的运行状况和状态的关键指标,以及 IT 系统需要提供的业务服务的类型。

解决方案架构师确定哪些业务需求可以通过对现有 IT 资产进行重用、修改或组合得到满足,哪些需要编写或购买新的 IT 资产。他们定义 IT 资产间的交互,包括消息交换的内容。

开发工作在三个角色中分配。实现人员编写新的应用程序代码,这些代码将通过服务接口调用。适配器开发人员构建包装现有或新采购的应用程序和软件包的服务,从而为其他服务提供可访问性。集成开发人员使用 ESB 的相关工具和技术构建逻辑,以控制请求在这些服务间路由的方式。


图 2. 用户角色
用户角色

解决方案管理员部署新的 IT 资产并将其服务定义导入到服务注册表中,从而使新的 IT 资产可用。当解决方案就绪后,操作人员将监视其执行,根据需要启动和停止 IT 系统,并给解决方案管理员提供建议(后者可能将据此调整解决方案配置)。







ESB 模式

集成开发人员和解决方案管理员会使用一组模式对 SOA 解决方案进行设计和部署。


图 3. 基本 ESB 模式的元素
基本 ESB 模式的元素

基本 ESB 模式将应用程序组件抽象为一个服务集,这些服务通过总线进行交互(而不是通过直接的点到点通信交互)。某个给定的服务既可以是提供者,也可以是请求者,或者同时兼有两个角色。任何 SOA 实现都会支持基本虚拟化,允许在不影响依赖请求者的情况下替换等效提供者实现。ESB 模式通过其对请求者/提供者交互的显式管理提高了此基本 SOA 功能。只要能提供与请求者所需的功能相似的功能,且 ESB 能对其进行协调,任何提供者都可以由另一个提供者替代。

ESB 提供了交互点,服务可以在此将消息放到总线上或从总线取走。它会对动态消息应用中介,并保证这些托管交互的 QoS。

从 ESB 的角度来看,所有的服务交互端点都是类似的,因为它们都发送或处理请求/事件;它们都要求特定的 QoS;它们可能都需要交互协助。ESB 模式允许集成开发人员以与处理新业务逻辑、流程编排组件或外部 Web 服务同样(面向服务)的方式对待与用户交互的请求者或提供者。

用于构建基于 ESB 的解决方案的模式分为以下几类:

  • 交互模式:允许服务交互点将消息发送到总线或从总线接收消息。
  • 中介模式:允许对消息交换进行操作。
  • 部署模式:支持将解决方案部署到联合基础设施中。







交互模式

ESB 允许端点通过总线以其本机交互模式进行交互。它支持各种端点协议和交互方式。交互模式的例子包括:

  • 请求/响应:处理端点间的请求/响应方式的交互。此 ESB 基于消息传递模型,因此由两个相关的单向消息流对请求/响应交互进行处理,一个用于请求,一个用于响应。
  • 请求/多响应:上述类型的变体,可以发送多个响应。
  • 事件传播:事件可以匿名分发到由 ESB 管理的相关方列表。服务可以将自身添加到该列表中。

图 4. 交互模式
交互模式






中介模式

中介模式处理总线上的动态消息(请求或事件)。由请求者发出的消息会转换为稍微有些不兼容的提供者(从潜在的端点集中选择)能够理解的消息。

这些中介操作单向消息而不是请求/响应对,因为 ESB 将交互模式放在中介模式上。


图 5. 中介模式
中介模式

中介有多种基本模式;更为复杂的模式可以通过组合简单模式构建:

  • 协议变换:允许服务请求者使用各种交互协议或 API(如 SOAP/HTTP、JMS 和 MQ Integrator——MQI)发送其消息。将请求代码转换为目标服务提供者的格式。可以应用到交互的请求者端或提供者端,或同时应用到两端或两者之间的任何位置。
  • 转换:将消息的有效负载(内容)从请求者的模式转换为提供者的模式。可以包含包封、反包封或加密。
  • 充实:通过添加来自外部数据源的信息(如由中介定义的自定义参数或者来自数据库查询的自定义参数)来增加消息的有效负载。
  • 路由:更改消息的路由,可从支持请求者的意图的服务提供者中选择。选择标准中可以包含消息内容和上下文、以及目标服务提供者的功能。
  • 分发:将消息分发到一组相关方,通常由订阅者的相关概要驱动。
  • 监视:在信息通过中介时观测其是否发生改变。可以用于监视服务水平;帮助确定问题或对用户进行后续支付使用的货币单位;或记录企业级事件(如价值超过一定数额的购买行为)。还可以用于将消息记入日志,以供审核和后续数据挖掘之用。
  • 相关:从消息或事件流中派生复杂事件。包括模式标识规则和响应模式发现的规则(例如,通过生成派生自触发事件流的内容的复杂事件)。

可以在解决方案中显式地配置中介。例如,集成开发人员可以配置一个 enrich 中介来修改消息内容。解决方案管理员可以配置一个 route 中介来允许其将某个服务提供者切换到脱机状态。

其他中介由 ESB 设置,以满足服务请求者和服务提供者的 QoS 要求。例如,如果服务提供者的安全策略声明要求使用加密消息,则 ESB 可以自动配置一个 encryption 中介。

策略同样也是服务的属性,解决方案管理员可以为交互(或交互集)设置策略。例如,为了将要发送到特定外部提供者或交易值超过 1 百万美元的所有消息记录到日志中。ESB 将通过配置中介(在本例中为monitor 中介)来实现策略。







复杂模式


图 6. 复杂模式
复杂模式

中介模式和交互模式可以进行组合,以实现更为复杂的模式。

例如,在协议变换后转换格式可以实现规范化适配器 模式,在这种模式中,所有相关方使用的消息和业务对象集都标准化为规范的格式。规范化适配器模式将端点的本机总线附加协议转换为标准协议,实现有效负载规范化,并在交付时进行这些转换的反向转换。

另一种常见的复杂中介是转换、记录和路由 模式。

网关 模式是一个复杂的协议变换变体。它可以合并转换和监视中介,以提供加密、日志记录或审核等功能。它还可以对一对多关系中的消息进行聚合和反聚合。服务门户是此类模式的代表,它为多个服务提供单一联系点,并隐藏内部服务的细节。







部署模式

解决方案管理可以选择多种 ESB 拓扑。下面是一些常见的例子:

  • 全局 ESB:所有服务共享一个名称空间,每个服务提供者对环境(异构、集中管理但分布在多个地理位置)中所有服务请求者均可见。供部门或小型企业使用,其中,所有服务都可能在整个组织中应用。
  • 直接连接的 ESB:公共服务注册中心使几个独立的 ESB 安装中的所有服务均可见。用于由业务部门提供和管理服务但整个企业中均可使用这些服务的场合。
  • 代理 ESB:桥接服务有选择地将请求者或提供者公开给其他域中的合作伙伴,从而控制多个 ESB 安装(每个安装都管理自己的名称空间)间的共享。ESB 间的服务交互通过实现桥接服务的公共代理进行。供各个部门使用,这些部门开发和管理自己的服务,但共享其中部分服务或者有选择地访问企业提供的服务。
  • 联合 ESB:将多个依赖 ESB 联合到其中的主 ESB。服务使用者和提供者连接到主 ESB 或某个依赖 ESB,以访问整个网络中的服务。供希望在一个监管部门的保护下联合有适度自治权的部门的组织使用。

图 7. ESB 部署模式
ESB 部署模式






结束语

ESB 模式扩展了 SOA 的虚拟化功能。可以由标准功能单元组成中介,然后进行部署,以帮助不匹配的请求者和提供者进行交互。ESB 还提供了用于部署和管理服务的通用模型。ESB 概念允许根据用户角色单独进行考虑,从而减少了单个工作人员的概念上的负担,并改进了体系结构的可用性。ESB 的综合编程模型、组件化工具以及基础设施极大地支持了 SOA 原则的提前实现。

posted @ 2006-04-17 03:49 wsdfsdf 阅读(340) | 评论 (0)编辑 收藏

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