UML软件工程组织
北京火龙果软件工程技术中心

SOA:我们是否重新发明了轮子?

 

作者:Nick Simha

 

简介

如果您加入IT行业已经有一段时间了,那么当您听说供应商们推出新的技术时,您会有似曾相识的感觉。如果您对于大量有关面向服务架构的宣传感到晕眩,那么您并不是惟一的一个。在最近的会议上,一个习惯于使用COBOL编码的与会者问道,SOA和他所使用的COBOL copybook之间的区别在哪里。我从未使用过COBOL copybook,但是曾见过大量的技术出现又消失,所以我可以理解这个问题。在本文中,我将说明隐藏在SOA背后的主要驱动力,以及如何改进技术以支持SOA。我将在概念层面上进行讨论,并在最后给出一些参考资料,以供想要深入钻研的人使用。

重用所面临的障碍

重用一直是软件开发的首要目标之一。这很明显:如果您编写了一段代码来实现某种功能,如果无需在其他很多地方再重新编写或维护它,那么无疑会提高生产率。然而,重用实现起来并不轻松,也并非自动化的。首先,必须以一种可重用的方式来组织或编写代码。然后,必须知道存在一段可以被重用的代码。在组织代码方面,不同的编程语言以不同的方式为重用提供内置支持。过程和函数是大多数程序员所熟悉的基本单元。面向对象的语言,比如C++和Java,还提供了定义和扩展自定义的类型或类的手段。这些特性背后的基本理念就是封装(也就是说,只需通过一些定义良好的接口来访问其中的功能,实现对于您而言是一个黑盒子)。这些特性有其用途和优点,但是当涉及到支持更大规模的重用时,它们也存在一些局限性。

  • 首先,这些编程语言工件是非常低级的,只有特别熟悉它们的程序员才能进行有效的重用。
  • 其次,即便是在同一个项目团队中,要发现可重用的资产也不是一件容易的事情,更不用说在企业范围内了。
  • 最后,这个层面上的代码并不支持网络,这意味着无法跨机器调用这些代码,也无法在另一种编程语言中透明地重用它们。例如,假定我已经使用C++编写了一个定价模块,那么不费一番工夫,我是无法在Java中调用这个模块的。

在这里我想表达的是,这些特性肯定有其用处,但是这个层面上的重用实际上就是剪切和粘贴代码,这易于出错而且不可扩展。

面向重用

“服务”这个概念的出现就是为了解决这些重用问题中的一部分。CORBA是对象管理组(Object Management Group,OMG)提出的一个标准,这或许也是使用基于标准的分布式计算模型来解决重用问题的首次全面努力。

其思路是,通过一个抽象接口正式实施封装的概念,并提供一组可由这些服务(或CORBA技术中的对象)使用的基础性服务。接口是使用一种叫做IDL(Interface Definition Language,接口定义语言)的语言定义的,而且为各种编程语言定义了映射。服务可以使用这种语言来描述。要使用某个特定的服务,只需使用IDL即可,而无需了解实现该服务的实际细节。这些服务还支持网络。这提供了一种跨硬件、语言和网络的便利途径。

CORBA还定义了一套丰富的基础性服务,比如用于注册和发现对象的目录服务(称为命名(naming))、基于公开属性发现对象的交易(trader)服务、用于异步通信的通知服务、事务服务,等等。所以,现在可以快速构建服务,因为可以利用这些基础性服务。还可以跨越多种边界轻松重用这些服务。其他的分布式组件模型,比如微软的DCOM和J2EE,都以一种或多或少类似的方式来构建和使用服务。

SOA到底是什么?

现在,我们已经准备给出面向服务架构(即SOA)的定义了。遗憾的是,关于SOA,存在多种定义,有时它们还相互冲突。很多定义都结合了一种特定的技术(特别是Web services),或者在定义中包含一种特定的特性(例如调用类型)。我将给出一些我认为抓住了SOA本质、而不是将其与特定的技术相关联的现有定义。但是,首先让我们看一看面向服务架构中的术语“服务”。

定义SOA中的服务

服务是一个被过度使用的术语,但是却没什么好的定义。服务就是一种能够以分布式方式调用的功能,它是定义良好的、自包含的,并且不依赖于上下文或其他服务的状态。让我们看一看构成服务定义的一些特征:

  • 能够以分布式方式被调用。这很重要,因为我们不能假定某个功能是处在客户端环境中。
  • 定义良好。正如早先讨论的那样,重用在编程语言层面上面临的一大难题就是难于发现可重用的资产并跨越各种技术使用它们。一个服务应该能够在一个众所周知的目录中描述和注册自身,而希望调用服务的客户端则应该能够完全基于已注册的信息来调用服务。
  • 自包含。一项操作的语义应该由即将进行的操作中的信息和服务状态所决定,而不应该依赖于其他某个服务的状态或上下文。这种隔离使得理解服务提供的功能和对其进行重用变得更加容易。

定义SOA

现在,让我们看一看一些SOA的不同定义。W3C把SOA定义为“一组可调用的组件,其接口描述可以被公开和发现”。我个人不太喜欢该定义中使用的组件这个词,因为组件是一个被过度使用的术语,会让人联想起特定的内容,比如ActiveX、EJB等等。然而,如果我们使用服务来代替组件这个词,那么这种定义是合理的。

ZapThink是一家行业分析公司,它把SOA定义为“一种架构准则,其中心内容是把IT资产描述和公开为服务。然后可以把这些服务以松散耦合的方式作为高级业务流程的一部分,从而在面临IT异构性时提供业务灵活性”。我较为喜欢这个定义,因为它使用了IT资产这个术语来定义SOA,范围更为广泛。此外,它还指出了SOA的一个重要特性——松散耦合(稍后将进行详细说明),并提及了SOA的优点。

最后一个定义来自于BEA的dev2dev站点的SOA技术中心,在这个定义中,SOA被定义为“一种设计方法,其目标是重用应用中立的服务,从而提高IT适应性和效能”。这是SOA在业务层的一个优秀定义。它强调了一个事实:SOA不仅仅是一个技术工件(像接口和协议一样),它其实是一种设计方法,具有最大化重用的明确目标。我想为这个定义添加一些内容:它不仅是设计方法(这只是前端部分),还是涉及到服务的整个生命周期——服务的设计、部署、维护和最后的停止使用——的方法。

希望这3个定义能够让您了解什么是SOA及其目标。在进入下一节内容之前,我想谈谈SOA的一个重要特性——松散耦合。耦合即组件相互依赖的程度。可以将服务设计在一起,即紧密耦合;也可以动态发现和使用服务。松散耦合是我们想要实现的目标,因为它可以降低服务或组件之间的相互依赖性,并让您可以轻松替换或更新服务。

SOA和分布式技术

从有关CORBA和J2EE的讨论中,您可以看到,这两种技术都提供了构建SOA的方法。这些技术已经跨不同行业进行过几次成功的部署。然而,如果要在企业级评估重用,那么即便是在已经部署这些技术的企业中,重用也没有达到应有的水平。在某些企业中,从业务的角度看,大量“服务”实际上都在执行同样的任务,比如验证信用卡、查找雇员等等,这种情况并非罕见。

为什么会存在这种重复呢?主要有如下两个原因:

  • 异构性或多中间件问题:一家典型的企业通常使用多种应用程序、工具和技术。同样的情况也适用于中间件:Java领域可能使用J2EE,而Microsoft领域则使用DCOM,诸如此类。从构建服务的角度看,这意味着可以通过多种方式描述接口(IDL用于CORBA,MDL用于DCOM,Java用于J2EE)。此外,由于每项技术都定义了自己的传输协议,所以有多种使用这些服务的方式。尽管人们曾经尝试搭建“桥梁”来连通这些技术之间的不同编程模型和传输协议,但实际的用户体验还是很糟糕:无法理解的映射(试试从Java到IDL的映射就知道了),这类“桥梁”的糟糕性能,供应商由于互操作性问题而相互责怪。简而言之,无论是定义还是使用服务的方式都不是通用的,从而影响了互操作性,而使重用难以实现。
  • 这些技术的复杂性:这些技术都相当复杂,难于学习,需要了解一个新的API和一个新的编程模型才能使用这些技术。使用这些技术构建服务需要编写大量的代码,尤其是对于CORBA来说。在这方面,J2EE做得要稍好一些,因为它支持使用更为声明式的方法来构建服务。然而,即使是J2EE也无法让人满意,因为程序员要掌握数十个API才能达到一定的效率。复杂性的另一方面体现在管理这些服务的生命周期上,例如,部署服务、对服务进行版本控制、停止使用服务。这些技术在这方面的支持很差,只有J2EE稍好一些,而CORBA和DCOM都有其各自的优点。然而,对于每个企业来说,有效地管理这些服务都是一件伤脑筋(且开销巨大)的事情。

所以,尽管分布式组件技术为构建SOA提供了明确支持,并且基于行业认可的标准,但上述两个因素在企业层面上妨碍了重用的实现。注意,实际的情况还要更糟,因为要使用这些基于标准的技术,企业需要让系统基于专用的中间件技术,比如MQ和TIBCO。所有这些系统,无论是基于标准的还是基于专用技术的,都应该被认为是企业的IT资产,因为在构建这些系统的过程中企业进行了大量的投资。这些现有系统中已经存在的功能必须被公开为可重用的服务,从而使用它们轻松构建新的系统。使用CORBA和J2EE的经验告诉我们,引入另一组API或另一种传输协议无法解决这个问题。我们需要做的是对消息格式进行标准化,并使用已经在企业中普遍应用的传输协议,比如MQ和IIOP。在下一节中,您将会看到Web services是如何满足这种需求的。

Web Services是救星?

Web services基于很多与Internet和Web相同的技术,它解决了分布式组件模型所具有的很多问题。我假定您已经对Web services有了一些基本的了解。对于想要快速入门的人,可以参考本文结尾处的参考资料部分。在这一节中,我将说明Web services是如何解决CROBA和J2EE之类的分布式组件模型的局限性的。

  • Web services使用HTTP作为其传输协议。HTTP已经被广泛采用和认可,这不仅有助于增强互操作性,而且使用现有的基础架构还可以提高操作效率。注意,Web services实际上是独立于传输协议的,HTTP只是可以使用的传输协议中的一种而已。可以对Web services使用已经在企业中普遍应用的传输协议,比如MQ和IIOP。
  • XML的使用。Web services使用XML来描述接口和需要在服务及其消费者之间交换的消息。可以使用Web services描述语言(Web services Description Language,WSDL)来描述通向某个Web服务的接口。尽管从表面看来,WSDL类似于IDL或Java接口,但是WSDL的功能更为强大,并拥有支持服务松散耦合的构件。例如,WSDL支持多个类型系统,所以可以使用它来描述使用大型主机类型系统的服务。它还支持多种协议和传输方式,例如,可以指定某个特定的服务基于JMS而不是HTTP可用。最后,借助于WSDL,可以以一种抽象方式定义Web服务的操作性行为,然后在不同的网络端点将其绑定到访问它的特定方式。
  • 承诺降低复杂性。分布式组件技术之所以复杂,原因之一就是它们规定了自己的编程模型,因此需要学习一组新的API。相比之下,Web services就没有指定任何新的编程模型,您可以继续使用您所熟悉的环境,包括J2EE或CORBA。这还意味着,可以选择使用任何编程语言——C++、Java、Perl。Web services其实是一种接合和消息传递技术。

从上面的讨论中可以看出,Web services实际上解决了与分布式组件模型相关的许多问题。Web services最适用于部署SOA。

然而,我们尚未完全实现这一目标。前面我曾提到过,当讨论与分布式组件模型相关的复杂性时,造成复杂性的主要原因是难于支持服务的整个生命周期,这不仅涉及到服务的构建,而且还涉及到对服务的部署、版本控制、保护和管理。我们还需要对服务的定义进行扩展,以便包容企业现有的资产,即使企业不是基于SOAP和WSDL之类的Web services技术。这包括在消息解决方案之外构建的集成,比如.NET、MQ Series、TIBCO和遗留及打包应用程序。为了支持真正的重用,我们需要打破企业中存在的屏障。我们还需要使这些服务的发现和使用更为轻松——这不仅涉及到程序员,而且还涉及到操作人员甚至是业务分析师。

服务基础架构:新兴解决方案

我们看到,行业基于共同的经验教训在继续发展。上述讨论不应该被理解为传统技术在企业中没有存在的位置或价值。我们仍然需要面向对象的编程语言,比如Java、分布式组件技术和消息传递系统,来构建新的系统。正如前面提到的那样,问题在于通过把这些系统中的功能看作服务并支持利用这些服务创建新的复合应用程序,从而跨现有的技术筒仓来支持重用。尽管使用现有技术进行手动构建是可行的,但是这样做既不轻松,也不经济有效。就像我们使用J2EE作为构建应用程序的基础架构一样,我们也需要一个类似的基础架构来组成、消费和管理企业中服务的生命周期。简而言之,我们需要服务基础架构(参见图1)。这类服务基础架构的本质特征应该包括:

  • 多中间件支持:CORBA、J2EE、MQ、Tuxedo——这些技术都在企业中用于集成。基于这些产品和技术构建的应用程序已经变成了一个筒仓,因为企业中可能会出现多个无法交互的“域”。服务基础架构应该允许企业基于合适的粒度水平在这些筒仓中公开有用的资产。有了用于发现这些系统中的元数据并基于它们自动创建服务的工具之后,这类服务的公开应该会变得更加容易。所有这类服务都应该以一种统一的方式被公开,并根据它基于的技术进行抽象,例如,我应该能够利用基于MQ的帐单编制功能和基于Tuxedo的呼叫处理功能构建一个新的复合应用程序,而不必学习有关MQ或Tuxedo的任何知识。
  • 对多种传输方式的支持:JMS、MQ、FTP、HTTP等都是现今在企业中普遍应用的传输方式,而且在不久的将来还将继续使用。服务基础架构不仅应该支持这些传输方式,还应该提供一种使用企业的专用协议或传输方式扩展它们的方式。另外,服务基础架构应该直接进行协议转换,而不应让服务使用像HTTP这样的通用协议。对于某些高性能的应用程序来说,这很重要,因为转换到标准消息或使用像HTTP这样的协议所带来的开销可能是不可接受的。
  • 服务的发布和发现:服务必须先被发现,然后才能被重用。需要使用某种形式的注册库来发现现有的服务(目录应该基于某种查询或浏览格式),从而注册或发布新的服务。另外,对这些服务使用的策略需要进行定义和注册,这类策略可以描述诸如使用服务的成本和安全特征之类的内容。
  • 服务运行时和生命周期管理:这涉及到监控服务的可用性、服务的故障恢复、服务的版本控制,或者停止使用服务。简而言之,必须提供高级的操作性支持。在前几代的集成和中间件产品中,管理和操作性支持似乎是马后炮。这给大多数企业造成了相当大的麻烦,并提高了成本。服务基础架构应该以操作性考虑为核心。另一个重要的方面是,由于可以在多个应用程序中重用服务,服务的不可用性将影响到依赖于它的所有应用程序。因此,应该提供用于服务版本控制和升级的特殊方式。
  • 对服务复合的支持:这涉及到使用现有服务构建新的复合应用程序。由于服务本身是应用中立的,可以用在服务的初始设计者预想不到的上下文中,所以必须支持消息转换、基于消息内容的路由和对一些简单条件逻辑的引入。
  • 服务安全性:安全性显然是一个大问题,所以必须支持基于某种策略、使用审计、警报触发机制的服务访问控制。此外,由于服务可以横跨具有其独有安全性模型的多个应用程序,所以必须提供与这些安全性模型的集成,从而提供端到端的安全性。
  • 易用性:服务基础架构本身不应该引入新的编程模型或API。它在本质上应该是高度声明式的,几乎或完全不需要编码。这应该由非常直观的可视化工具提供。

图1.服务基础架构的基本要素

我们的目标达到了吗?

服务基础架构在支持SOA和增强重用方面走了很长一段路。这代表着整个行业在支持重用和简化系统构建方面所做出的共同努力。毫无疑问,基于在部署利用这类基础架构的新应用程序方面的经验,整个行业将会继续发展。很多公司都很关心Web services标准的数量,其中一些标准是由相互竞争的供应商阵营所驱动的。供应商之间需要进行更多的合作,不仅要快速聚合Web services和安全性领域中的一些重要标准,而且要解决实际的测试和验证问题,这样才不会由于产品的互操作性而给客户造成不便。

我列出了一组有关服务基础架构的长长的需求清单。好消息是市场上已经出现几种支持其中绝大部分功能的产品。然而,有一点必须意识到:仅仅通过购买一种声称支持这些特性的产品,企业还不能拥有能够交付灵活性和敏捷性价值的服务基础架构。SOA和支持SOA的服务基础架构是可以转换的,因此需要对组织、流程管理和文化进行更改。IT组织应该实施架构一致性,并使自身与其业务风险承担者之间的同盟关系更加紧密,以便在进行转换时获得支持和资金。流程应该按照如何交付服务以及如何管理SOA中参与者之间的相互依赖性进行定义。一些被大多数应用程序重用的服务可以是水平的和一般性的,其他的则可以专门用于一些选定的应用程序。一个涵盖如何为这些服务提供资金以及如何开发这些服务的管理模型颇为重要。最后,文化应该鼓励和奖赏对现有服务的重用,而不是从头开始构建一切。

所有这些内容听起来可能令人生畏,但是实际情况是,这确实是一项令人生畏的任务。然而,现在出现了一些有利于开发的好兆头。首先,Web服务互操作性(Web Service Interoperability,WS-I)小组特别制定了图表,以便改进跨不同实现的Web服务互操作性。供应商们基于WS-I提供的配置文件进行互操作性测试。尽管这看起来似乎是明显应该做的事,但是CORBA或J2EE并非如此。而专用中间件和EAI产品的情况则更为糟糕。第二个好消息是,用于构建服务基础架构的工具已经越来越成熟,而且更加易于使用。例如,BEA的AquaLogic Service Bus产品是完全配置驱动的——几乎所有任务都能够通过一个图形界面来完成。最后,许多企业都已经部署了SOA,并且已经在应用程序开发速度和成本方面获益。更加成熟的IT组织已经获得了围绕其实现的这些指标和最佳实践,并向它们的企业证明了敏捷IT可以成为多么具有竞争力的区分点。

原文出处:http://dev2dev.bea.com/pub/a/2005/08/soa.html

 


版权所有:UML软件工程组织