在过去十年中,分布式计算已经成为了一种在越来越分散的计算资源中保持互操作性的重要手段。远程过程调用(RPC)是目前分布式系统之间进行通信的最常用手段,但是,将应用分布在多层次的、基于组件的架构上的选择仍十分有限。不过随着时间的发展, Internet使分布式计算具有了新的潜力,并且随着昨天的业务应用升级为明天的Web服务,人们对分布式计算提出了新的要求。
以SOAP为基础的Microsoft的.NET显现出减少实现RPC的困难,快速实现互操作性的潜力。对象管理组(OMG)提出的CORBA一直是得到承认的企业规模的分布式计算环境(特别是Unix平台和专用大型机环境)的中间件互操作标准。
与SOAP不同,CORBA不是一种标记语言,进一步地说,CORBA起到一种中介的作用,它方便了分布式的、面向对象的应用之间的连接并使通信成为可能,不管应用安装在何种平台上。
所有这些功能是以额外的开销为代价的。CORBA以难于开发和部署而闻名。对于较小的工程而言,CORBA在代码开发上所需要的额外费用和努力通常不会超过其性能好处。
随着基于XML的BizTalk Server 2000的发布,Microsoft开始通过跨越平台边界填补B-B产品线中的空白。由于SOAP不仅限于Windows、Java或纯企业环境,此举还使Microsoft产品得到广泛的应用。
Microsoft的.NET技术还使开发人员可以方便地利用SOAP接口。任何Visual Basic开发人员无需成为XML/SOAP专家,就可在Internet上创建应用对象。
尽管SOAP具有简单性的好处,但是它为此付出了代价:SOAP中的XML数据必须被提取和解析,因此降低了性能。与CORBA的二进制数据相比,SOAP基于文本的消息在传输中消耗了大量带宽。
CORBA远未被排除在开发人员的发展计划之外。OMG在保证CORBA与新出现的通信协议之间的兼容性上采取了重要的步骤。因此,现在有许多能够将SOAP请求转换为CORBA调用的桥梁,其中包括开放源代码工程。
在Web服务领域,CORBA甚至可能具有已经部署到位的语言捆绑和服务API的暂时优势。CORBA的IDL(界面定义语言)可以发挥与Web服务模型中所使用的WSDL(Web描述语言)类似的服务和语法描述机制的作用。
但是,在Internet访问和设置方便性极为重要的环境中,SOAP将能改进跨平台的功能。随着处理器和网络速度的增加,许多SOAP的限制将变得不重要,从而使SOAP成为更多企业工程中更好的全面选择。
CORBA服务的基本内容
在CORBA体系规范中定义了多种类型的服务(Service),如命名(Naming)、生存期(LifeCycle)、事件(Event)、事务(Transaction)、对象持久化(Persistent Objects)、查询(Query)、特征(Property)、时间(Time)等服务功能。CORBA服务与对象请求代理之间的关系如下图所示。
在CORBA规范中,没有明确说明不同厂商的中间件产品要实现所有的服务功能,并且允许厂商开发自己的服务类型。因此, 不同厂商的ORB产品对CORBA服务的支持能力不同,使我们在针对待开发系统的功能进行中间件产品选择时,有更多的选择余地。
下面介绍与分布式应用程序设计和开发关系密切的CORBA服务内容:
1. 对象命名服务(Naming Service)
在命名服务中,通过将服务对象赋予一个在当前网络空间中的惟一标识来确定服务对象的实现。在客户端,通过指定服务对象的名字,利用绑定(Bind)方式,实现对服务对象实现的查找和定位,进而可以调用服务对象实现中的方法。
2. 对象安全性(Security)服务
在分布式系统中,服务对象的安全性和客户端应用的安全性一直是一个比较敏感的问题,安全性要求影响着分布式应用计算的每个方面。对于分布在互联网中的分布式应用来讲,为了防止恶意用户或未经授权的方法调用对象的服务功能,CORBA提供了严格的安全策略,并制定了相应的对象安全服务。安全服务可以实现如下功能:
● 服务请求对象的识别与认证;
● 授权和访问控制;
● 安全监听;
● 通信安全的保证;
● 安全信息的管理;
● 行为确认。
CORBA系统将对象请求的安全性管理的功能交由ORB负责,系统组件只需负责系统本身的安全管理,使得基于分布式应用在安全性控制方面的责任十分明确。
3. 并发控制(Cocurrency Control)服务
CORBA规范中定义并发控制服务的目的在于实现多客户访问情况下的并发性控制和对共享资源的管理。
并发控制服务由多个接口构成,能够支持访问方法的事务模型和非事务模型。由于两种模型的引入,使得非事务型客户在访问共享资源时,如果该资源被拥有事务模型的方法锁定(Lock),则该客户转入阻塞状态,直到事务型方法执行结束,将共享资源锁打开,非事务模型的客户才能够访问该共享资源。
并发控制服务使多个对象能够利用资源锁定(Lock)的方式来对共享资源进行访问。在访问共享资源之前,客户对象必须从并发控制服务中获得锁定。在确认资源目前正在空闲时,获得资源的使用权。每个锁定是一个资源-客户对,说明哪个客户正在访问何种类型的资源。
4. 对象生命期服务(LifeCycle)
CORBA中的生命期服务定义和描述了创建、删除、拷贝和移动对象的方法。通过生命期服务,客户端应用可以实现对远程对象的控制。
利用命名(Naming)服务
实现分布式应用
在上篇文章中介绍的利用JavaIDL开发分布式应用时曾采用命名服务的方式。对象命名服务是ORB查找服务对象实现的一种简单的方式。
1. 功能需求分析和定义接口文件
本例的主要功能是模拟电话用户注册及电话号码查询业务,开发基于命名服务的分布式应用程序,中间件产品采用VisiBroker 4.5.1 for Java。
根据系统功能的定义,两种业务均属于电信业务的经营范围,因此定义模块名TeleCom。电话号码注册为电信业务管理功能范围,需定义该功能接口Registry,该接口内包含用户注册方法register();电话号码查询为用户服务功能范围,需定义接口User,该接口内包含查询个人电话号码方法getNumber()。经过上述分析后编写的IDL接口定义文件TeleCom.idl如下:
module TeleCom
{ interface User //接口User声明
{ //接口中getNumber方法的定义
int getNumber();
};
interface Registry //接口Registry声明
{ //接口中register方法定义,其中以string类型变量作为输入参数 ’方法返回User对象
User register(in string name);
};
};
上述接口定义文件经idl2java编译后,在当前接口文件目录中生成TeleCom子目录,该目录中包括UserPOA.java、RegistryPOA.java等文件。这些文件是客户端和服务对象实现功能的框架以及相关的支持文件。有兴趣的读者可以实际创建IDL文件,经IDL到Java语言的映射后,分析生成文件的格式。
2. 实现服务功能
(1)实现User接口的类UserImpl
根据系统分析确定的功能,定义接口User对应的实现类UserImpl的代码如下:
// UserImpl类继承定义在UserPOA.java中的UserPOA类
public class UserImpl extends TeleCom
.UserPOA
{ private int aNumber;
//构造方法
public UserImpl( int number )
{ aNumber = number;
}
//接口中定义的方法,用于返回该用户对象对应的电话号码
public int getNumber( )
{ return aNumber;
}
}
(2)实现Registry接口的类RegistryImpl
根据系统分析确定的功能,定义接口Registry对应的实现类RegistryImpl的代码如下:
// RegistryImpl类继承定义在RegistryPOA
.java中的RegistryPOA类
public class RegistryImpl extends TeleCom
.RegistryPOA
{ public synchronized TeleCom.User register( String name )
{ //根据用户名name生成注册的电话号码
//根据指定的电话号码,生成User接口的实现类UserImpl
//激活可移植对象适配器
//将注册的用户对象存入对象库
}
//返回用户对象的实例
}
3. 实现服务器端应用
根据功能描述及采用的ORB命名对象服务策略,按如下方式实现服务器端应用程序:
首先对ORB进行初始化,并获取根POA(RootPOA)的引用。通过在根POA中解析命名服务获得命名服务上下文,并根据服务对象的功能要求以相应的策略创建用户POA,利用用户POA完成服务对象端ORB与服务对象实现的通信。
服务对象的代码框架为:
public class Server
{ public static void main(String[] args)
{ //初始化对象请求代理
org.omg.CORBA.ORB orb = org.omg
.CORBA.ORB.init(args,null);
//获取根POA的引用
POA rootPOA =POAHelper.narrow(orb.resolve_initial_references(“RootPOA”));
//引用命名服务,获取上下文内容
org.omg.CORBA.Object rootObj =
orb.resolve_initial_references(“NameService”);
NamingContextExt root =
NamingContextExtHelper.narrow(rootObj);
//创建POA服务策略
org.omg.CORBA.Policy[] policies =
{ rootPOA.create_lifespan_policy(LifespanPolicyValue.persistent) };
//根据服务策略创建用户可移植对象适配器
POA myPOA = rootPOA.create_POA(“TeleCom_POA”,rootPOA.the_POAManager(),policies );
//生成服务对象
//申请服务对象标识
//激活服务对象
//激活可移植对象管理器
rootPOA.the_POAManager().activate();
//启动ORB
orb.run();
}
}
4. 实现客户端应用
根据服务对象端提供的命名服务类型,生成相应的对象请求代理,并利用命名服务的方式定位服务对象,提出服务请求。
public class Client
{ public static void main(String[] args)
{ //初始化对象请求代理
org.omg.CORBA.ORB orb = org.omg
.CORBA.ORB.init(args,null);
//引用命名服务,获取上下文内容
org.omg.CORBA.Object rootObj = orb.resolve_initial_references(“NameService”);
NamingContextExt root = Naming-
ContextExtHelper.narrow(rootObj);
//利用命名服务定位服务对象
//其中服务对象名已经在Server.java中定义
org.omg.CORBA.Object mgrObj = ((NamingContext)root).resolve(root.to_name(“TeleComManager”));
TeleCom.Registry manager = TeleCom
.Registry.narrow(mgrObj);
//取得账户名name
//根据具体账户名申请用户账户
TeleCom.Registry user = manager.open(name);
//获取用户分配的电话号码
int number = user.getNumber();
//打印账户信息等操作
}
}
<. language=. src="/js/contentad.js"> 对象标准COM和CORBA论长道短
组合软件是新一代软件技术发展的标志,它的提出很自然,为了提高软件生产力、不草率地开发应用程序、设计开发人员应尽可能地利用可重用的软件组件、组装构造新的应用软件系统。
追根求源,由软件模块组件组织合成软件的思想早在70年代就已提出了,函数就是一种组件,函数通过参数来适应不同应用需求的变化,Ada语言的模块package就是一种组件,实现了内部细节掩藏,模块通过接口规范说明进行连接和组装,package还提供了类属机制,使模块通过类属参数,适应不同应用需求的变化。但是,传统软件系统结构的局限性,以过程为中心设计的功能模块,其扩充和复用的能力都较差,对模块进行应用重组的困难很多。从80年代开始的面向对象技术的研究,使组合软件又萌发出新的生命力。面向对象的软件,以数据为中心设计,对象类既具有模块的封装性和类属等特性,还具有继承特性
,极大地提高了类的可扩充性和可再用能力。对象类较之于传统软件的功能模块而另具有的优点是:
(1)易于理解,具有完整的语义特征;
(2)易于扩充和修改,具有较高的通用性和适应性;
(3)易于构造组装,具有规范的外部接口。
开发应用组件必须遵循标准,以保证软件组件的互操作性,只有遵循统一的标准,不同厂商的、不同时期的、不同程序设计风格的、不同编程语言的、不同操作系统的、不同平台上的软件或软件部件才能进行交流与合作。为此,OMG(ObjectManageGroup)提供了一个对象标准CORBA,它定义了一个网连对象的接口,使得对象可以同时工作。基于CORBA的对象请求代理ORB为客户机/服务器开发提供了中间件的新格式。
令人称奇的是,作为OMG成员的微软公司却撇开CORBA而另辟了COM(ComponetObjectModel),即组件对象模型,并把COM定位成基于对象的软件开发模型,尽管COM被认为是微软鼓噪出来的技术,但支持COM的开发工具却不断增多,其中大部分来自于微软,包括VisualBasic和VisualC++。
面对组件领域内缺乏一个统一的、用于开发应用组件的标准这种局面,开发人员应怎么办呢?COM和CORBA谁更胜一筹?本文先介绍CORBA和COM,然后分析比较这两个标准及其组件的优劣势,相信读者在读完本篇文章之后,会
做出自己的判断和取舍定笃。
一、公共对象请求代理结构:CORBA标准
全球性网络使线上的所有设备和软件成为全球共享的浩瀚的资源,计算机环境也从集中式发展到分布式环境,开放式系统的发展使用户能够透明地应用由不同厂商制造的不同机型不同平台所组成的异构型计算资源,因此,分布式处理和应用集成自然而然地成为人们的共同要求,那么什么是分布式处理和应用集成呢?它们的功能和关键技术是什么呢?简单地讲,分布式处理和应用集成就是指在异构的、网络的、物理性能差别很大的、不同厂商的、不同语言的信息资源的基础上构建信息共享的分布式系统,并且能够有效地进行应用系统和分布式处理的集成。分布式处理的关键在于定义可管理的软件构件,即面向对象技术中的“对象”。应用集成的关键在于为跨平台、跨机种、跨编程语言的产品提供统一的应用接口。OMG组织针对当今信息产业的要求,公布了CORBA标准,即公共对象请求代理体系结构(Common Object Request Broker Architecture),这是一个具有互操作性和可移植性的分布式面向对象的应用标准。
CORBA的结构见下图:
CORBA的核心是对象请求代理ORB,它提供对象定位、对象激活和对象通讯的透明机制。客户发出要求服务的请求,而对象则提供服务,ORB把请求发送给对象、把输出值返回给客户。ORB的服务对客户而言是透明的,客户不知道对象驻留在网络中何处、对象是如何通讯、如何实现以及如何执行的,只要他持有对某对象的对象引用,就可以向该对象发出服务请求。
CORBA允许用户以两种不同的方式提出对象请求:
1)静态调用:
通过给定接口的存根,在编译了对象代码后,进入客户端的程序。因此,静态调用必须在编译时就知道对象及其类型。
2)动态调用:
通过ORB的动态调用接口DII,在运行时生成访问对象的代码。
不管客户以哪一种形式提出请求,ORB的任务是:找出所要对象的位置,激活该对象,向对象传递此请求。对象执行所请求的服务后,把输出值返回给ORB,然后再由ORB返回给客户。
CORBA的重要概念是:
1.对象连接
CORBA广泛地支持对象的实现,在单服务器系统中也可以实现由接口定义语言定义的接口。ORB的灵活性既可以直接集成已有的应用,又不会使新对象受某些原则的制约。
对象连接提供了有不同类型对象实现时,使用ORB服务的方法,服务包括:对象引用、方法调用、安全控制、对象实现的激活与静候等。
2.接口定义语言(IDL)
CORBA用IDL来描述对象接口,IDL是一种说明性语言,它的语法类似于C++。
IDL提供的数据类型有:基本数据类型、构造类型、模板类型、和复合类型、操作说明。这些类型可以用来定义变元的类型和返回类型,操作说明则可以用来定义对象提供的服务。
IDL还提供模块构造,其中可以包含接口,而接口是IDL各类型中最重要的,它除了描述CORBA对象以外,还可以用作对象引用类型。
IDL提供了接口继承性,派生接口可以继承其基类接口所定义的操作与类型。IDL的接口继承性有其特殊性,此处不赘述。
总之,CORBA的IDL是一种说明性语言,描述面向对象系统开发所遵循的接口与实现相分离的基本原则。
3.动态调用接口
把IDL说明编译成面向对象程序设计语言的实代码后,客户可以调用已知对象的操作。在某些应用中,用户并不了解应用接口编译信息,但也要求调用对象的操作,这时就要动态调用接口来调用用户的操作了。例如,图形用户接口应支持用户浏览接口公共库,以获得每个对象所支持的操作信息,用户可根据自己的需求从浏览对象中挑选出所需的对象操作,具体的对象操作的调用实际上是用动态调用接口来完成的。
4.接口公用库
接口公用库持久地存储IDL的接口说明,借助于接口公用库,可以实现对象继承性层次结构的导航,并且提供了有关对象支持的所有操作的描述。接口公用库最常见的功能是为接口浏览器提供信息,帮助应用开发者找出潜在的可重用的软件部件。ORB可以利用接口公用库检查运行时的操作参数类型,但接口公用库的基本功能是提供类型信息,为动态调用接口发送请求提供信息支持。
二、组件对象模型:COM标准
COM是微软公司推出的与CORBA抗衡的产品,在设计开发COM时,微软把COM定位成基于对象的程序设计模型,旨在促进软件的互操作性,实际上它是基于OLE的组件标准,COM采用了OLE的对象请求代理,定义了OLE组件对象及应用之间的接口。
COM所涉及的重要概念有:
1.COM接口
COM的应用程序之间以及应用程序与系统之间是要相互交流信息和相互作用的,其相互作用是通过一系列的函数实现的,这些函数就叫作“接口”或“界面”。COM接口是组件与组件之间缔结的契约,提供了特定层次上的服务或功能性。
COM接口提供了以下的便利:
・无需重新编译,对象就可以增添新的功能;
・能够透明地向另一个过程或另一台机器上的对象发送RPC调用;
・诸如C、C++、Pascal、Ada和Smalltalk等凡是支持指针结构并通过指针能显式地或隐式地调用函数的程序设计语言都能够创建并使用COM对象。
COM定义了一种特殊的接口IUnknown来实现一些基本功能,所有对象均支持此基本接口,该接口的方法是QueryInterface,它允许对象的用户在运行时动态地确定COM对象是否支持某一个接口。
COM的接口定义语言是COMIDL(Interface Definition Language),它是OSFDCE所采用的IDL的一种简单扩展,DCE,即分布式计算环境,是OSF(Open Software Foundation)组织提供的一组独立于各平台的中间件服务,它使得分布的应用程序得以协调运行。
开发人员可以使用COMIDL来创建对COM对象的接口方法的说明。
2.用GUID来标识对象和接口
未来的分布式对象系统可能大到拥有数百万个接口,而软件的组成部件是必须唯一标识的。在大型复杂系统中,如果仅用便于人类阅读的名称来标识组件的话,那么几乎是100%要出现名字冲突现象的。为了避免这种事件的发生、解决名字冲突问题,COM采用了全局唯一的标识符GUID(Globally Unique Identifier),每个GUID都有128位整数并能确实保证标识符在空间世界和时间世界中的唯一性。COM的GUID和OSFDCE的UUID(Universally Unique Idenfifiers)是完全等同的。
3.摒弃继承性而采用聚类
微软认为在松散耦合的、分散的、逐步改善的对象系统中,继承性是造成很多麻烦的根源,但微软也承认如果程序设计人员都能控制继承性层次,那么实现继承是一个十分有用的技术,且紧耦合也不会带来太多的麻烦。不过微软还是认为在实现层次上看,对象与对象之间的契约是不言明且有二义性的,当父或子组件改变了实现,那么与其有关的组件的行为就成为非定义行为了。
COM提供了两种机制来取代实现继承性,这两种代码重用机制叫作抑制/代理和聚类,在前一种机制中,一个对象(外部对象)只要把内部使用的对象当作服务提供者来使用就可以使自己(外部对象)成为其他对象的客户了,外部对象的客户是绝不能看到内部对象的,这就是说某个对象的内部对象对于该对象的客户来说是完全隐藏的,这正是封装性的体现。
在聚类机制中,一个聚类对象实际上是一个合成对象,由外部对象和内部对象合成,外部对象把内部对象直接呈现给外部对象的客户,这时内部对象就象外部对象中的一部分一样,所以说聚类机制是一种特殊的抑制/代理机制。
4.本地透明性和远端透明性
COM允许客户透明地与对象通讯,客户在与对象通讯时并不知道对象在何处,客户访问对象完全是通过接口指针的,指针当然是在过程中的,而且每一次对接口的调用都要先与过程中的一些代码打交道。如果对象是在过程中的那么就可以直接调用该对象,若对象在过程之外,那么调用先与COM提供的代理对象打交道,产生一个远程过程调用,以调用其它过程中的或其它机器上的对象。
5.COM库
COM的核心就是规范说明对象及其客户的接口,COM本身也包含了一些系统级的代码,因此COM也有自己的实现,COM库就是系统组件,提供了COM机制。微软公司在Windows平台上的COMOBJ.DLL就是COM库的实现,WindowsNT和Windows95平台上COM库的实现是OLE32.DLLE。
三、COM与CORBA的比较
这两种标准的主要区别在于它们实现接口的方式:COM规定了一系列组件必须实现的接口,组件对象之间的相互作用必须经由这些接口,所有这些接口都必须由基接口IUnknown导出;CORBA则不规定基类,各厂商可以根据自己
的意愿去实现自己的类。
CORBA标准没有关于引用实现的规定,这是OMG考虑到各厂商切身利益而故意忽略的,而没有关于实现细节的明确规定这既是一大优点同时也是具有很多局限性的,因为在为厂商提供实现灵活性的同时,也招致了许多麻烦。如
无法统一管理、ORB不兼容、和缺乏可移植的服务器等问题。与此相反,COM则非常明确地规定了实现细节,但这种严格控制也能导致不良后果:解决方案不是最优方案。
COM与CORBA另一差异在于对实现继承性的不同处理,实现继承即是面向对象技术利用类层次中而实现的类的继承。接口继承性是指能够不依赖类层次而重用对象接口的能力,它体现了OO中的封装性的概念。微软则不以为然,它认为把实现继承应用到相互作用的对象模型中去是不恰当的,所以COM只支持接口继承而不支持实现继承。
IBM则声称一个真正的面向对象系统必须支持实现继承性,IBM在其SOM中实现了实现继承性。SOM是CORBA家族中的第一个成功产品,它诞生于1991年,IBM认为SOM是面向对象的,而COM则是基于对象的。
关于COM和CORBA这两大标准,还有一个不容忽视的问题�D�D�D产品的级别和产品的种类。CORBA有许许多多的产品,支持跨网络的对象的相互作用。微软的OLE是COM产品,但它还不支持跨平台的对象的相互作用。
综上所述,Microsoft身为OMG成员却不支持CORBA标准而另辟COM标准,使COM成为CORBA及其已实现组件OpenDoc的直接竞争者。由于OMG的其他成员都没有把桌面软件作为战略重点,加上微软在桌面软件行业中已成为事实的霸主地位,COM实际上就成为桌面市场的工业标准。Digital已决定把COM移植到OpenVMS和OSF/1平台上,并建造沟通COM和CORBA的桥梁。微软正雄心勃勃地发展WindowsNT操作系统,以图取代UNIX操作系统在服务器领域的地位,鉴于微软的实力及其市场占有率,这种可能性是很大的。如果在几年后,微软的愿望成为现实,大多数服务器厂商以WindowsNT做为服务器品质操作系统,那么分布式COM也就成为分布式互操作对象领域中的主角了。对于许多应用和开发环境来说,为了平衡基于组件开发的优势,COM可能
是明智的选择,在软件愈来愈复杂和专用的今天,基于组件的开发是不破坏整体性而控制软件复杂性的行之有效的方法。