简介
CORBA是OMG组织在1991年提出的公用对象请求代理程序结构的技术规范。CORBA有很广泛的应用,它易于集成各厂商的不同计算机,从大型机一直到微型内嵌式系统的终端桌面,是针对大中型企业应用的优秀的中间件。最重要的是,它使服务器真正能够实现高速度、高稳定性处理大量用户的访问。现在很多大型网站后端的服务器都运行CORBA,其中有些网站您可能每天都在访问1。
CORBA的底层结构是基于面向对象模型的,由OMG接口描述语言(OMG Interface Definition Language,OMG IDL)、对象请求代理(Objec tRequest Broker,ORB)和IIOP标准协议(Internet Inter ORB Protocol,也称网络ORB交换协议)3个关键模块组成。
使用接口描述语言编写的对象接口,使得与语言无关的独立性成为可能。IDL使得所有CORBA对象以一种方式被描述,仅仅需要一个由本地语言(C/C++、CORBA或Java)到IDL的“桥梁”。CORBA对象的互通信要以对象请求代理为中介,这种互通信可以在多种流行通信协议(如TCP/IP或IPX/SPX)之上实现。在TCP/IP上,来自于不同开发商的ORB用IIOP标准协议进行通讯。
我们知道,为了保持CORBA的商业中立性和语言中立性,必须有一个中介,存在于像C++CORBA服务器代码和JavaCORBA客户机这样的实体中间,这就是IDL。一个底层对象的若干相关方法和属性被IDL集入一个单一接口。一旦IDL接口定义完成,它可以以Stub码或框架代码的形式编译成所选用的语言。在所有的ORB中都有IDL编译器。
值得注意的一点是,IDL不同于其他的面向对象程序设计语言,我们不能用它指定所定义的类或方法的具体实现。因此,仅仅将它作为一种定义底层对象接口的语言要好得多。
CORBA基本构件CORBA结构示意图如图所示2。
公共设施公共设施分为两类:
横向设施(horizontal facilities)是指在通用领域内定义的对象。信息管理、网络管理、系统管理、任务管理和用户接口等都属于通用领域。
纵向设施(verticalfacilities)是指在专用领域内定义的对象。电信、财政、商务、卫生保健等都属于专用领域。
对象服务对象服务是为公共设施和各种应用对象提供的基本服务,如命名服务、事件服务、事务处理服务、通知服务、交易服务、生命周期服务和安全服务等等。
命名服务(naming service)。CORBA对象登记在命名服务中,它可根据对象的名字找出对应的服务器中的对象引用。
事件服务(event service)。事件服务由一个或多个供应者(supplier)、消费者(consumer)以及事件通道(event channel)组成。后者是供应者和消费者之间传送事件(消息)的媒介。供应者把要送给消费者的消息放到事件通道中,根据事件通道的工作方式———推模式(push)和拉模式(pull),这些消息或者被推至消费者,或者由消费者主动将它们从通道拉出。
事务处理服务(transaction service)。它确保一个事务所包含的操作,要么全部成功执行,要么在失败的情况下一个也不执行并恢复到初始状态,以维持执行事务前后数据的一致性。
交易服务(trader service)。交易服务由出口者(exporter)、进口者(importer)和交易者(trader)组成。出口者向交易者给出服务的描述和通告,进口者向交易者查询符合有关条件的服务信息,然后从出口者获得所需要的服务。
生命周期服务(life cycle service)。通过直接面向对象的服务,如对象的建立、删除、转移和复制等来控制对象的生存期。
安全服务(security service)。CORBA一级安全服务提供鉴权、限权、授权、审计、加密以及登记注册等服务,全面解决分布系统中的安全性问题。
通知服务(notification service)。它是事件服务功能上的扩充,增加了结构化事件,事件的过滤机制以及服务质量控制等功能。
应用对象这是未经OMG标准化的、由各个应用开发者自行开发的实体,应用对象使用CORBA提供的各种对象服务。
对象请求代理对象请求代理(ORB: Object Request Broker),它是CORBA的基础,是在分布环境下,CORBA应用所使用的、基于对象模型的软件总线。它的基本职责是解决对象引用的请求和建立应用对象之间的联结,通过标准接口,使这种联结独立于所使用的硬件和软件的平台,从而保证了对平台的透明性以及对操作系统、网络协议和编程语言的透明性。
接口定义语言接口定义语言(Interface Definition Language,IDL)用来定义CORBA对象使用的、应用组件之间的接口。它不是过程语言,它只能定义接口,而不是去实现某个接口。IDL独立于任何编程语言,用IDL编译器可以将它映射为其他常用的语言,如C++,C,COBOL,Java等等1。
IDL的框架主要包括四种元素:
模块(module)。它含有许多按功能进行分组的接口,形成附加的分层结构。因此,模块定义了一个命名空间。
接口(interface)。它定义了数据和操作(或称为方法),供客户调用。接口中可以包括类型、常量、属性和异常的声明。实际上,IDL接口定义了CORBA中的类。
操作(operation)。它表示客户可以调用的、处于对象中的服务。操作特性(signature)指的是操作的参数和返回的结果类型。一个操作还可以包括可供选择的异常事件和一组描述客户语言环境的属性。这样,操作就定义了CORBA中的方法。
数据类型。它用来描述参数、属性、返回值以及异常等的允许值。类型是一种可标识的实体,具有一个与其值相同的谓词,如果它作用于某个实体得到的结果为真,那么,这个实体就满足这种类型,称为该类型的成员。CORBA所支持的数据类型可以是基本类型、模板类型、构造类型、复杂类型以及本地类型。
ORB核心作用对象的定位当客户端程序得到对象引用(Object Reference)之后,会调用该对象引用的操作。这时,客户端的ORB会根据对象引用中的信息来定位对象的实现(具体定位的方法将在后面章节讨论),并确保该对象实现可以接受请求。由于ORB可以根据对象引用来定位服务器,因此客户端程序不必关心对象是在哪里实现的。客户端对远端对象发起调用,就好像调用本地对象一样,从而实现了CORBA的位置透明的特性。
编组与解组在客户端发起调用的时候,输入参数格式都与特定平台和特定语言有关,客户端ORB负责将它们编码成可以在网络上传送的格式,或称在线格式(on-wire format),这一过程称为编组(marshalling)。这种“0101”的格式在网络上传送后到达服务器端的ORB,服务器端的ORB负责将这些在线格式“还原”成本地所使用的特定平台和语言的格式,这一过程称为解组(unmarshalling)。与此相反,当服务器端调用结束以后,服务器端ORB负责将输出参数和返回参数编码成在线格式,并经网络传送到客户端ORB,客户端ORB再将这些在线格式“还原”成本地所使用的特定平台和语言的格式,作为输出参数和返回参数送给客户端程序。总的来说,编组与解组的重要性表现在:第一,它把对远端对象的调用变成一维的有序码流,有利于在网络上的传送。第二,它提供了一个独立于各平台和语言的“中间格式”,不同的平台上的不同语言通过这个“中间格式”进行“对话”“(中间格式”的规则,将在后面章节中叙述)。正是由于编组和解组的引入,使客户端和服务器端的平台和语言可以不同,带来了CORBA的平台独立与语言独立的特性。
启动初始服务在程序初启的时候,需要得到一些通用的对象引用,如对象适配器、命名服务、接口库的对象引用。由于处于程序初启的特殊阶段,这些对象引用很难用常规的方法得到。ORB可以通过伪对象接口CORBA∷ORB提供两个操作以完成这项功能:list-initial-services()和resolve-initial-references()(详见“ORB初始化”一节)。
屏蔽底层网络协议ORB负责处理底层网络通信的细节,它可以使用不同的底层网络协议,例如TCP/IP,IPX,SS7等,从而将客户与服务器从复杂的网络编程中解脱出来。
提供接口库和其他的API每个ORB都有一个接口库,接口库负责存储用接口定义语言(IDL)定义的接口的信息,它还支持一些标准的API,用来遍历或查询系统中的接口信息,它是CORBA动态调用不可缺少的组成部分。此外,ORB还通过伪对象接口CORBA∷ORB提供其他的通用API,这部分API既可以为客户程序使用,也可以由服务器程序使用(有关这部分的内容,将在“ORB接口”一节详细介绍)。基于以上的讨论,可将ORB核心的作用归纳如下(见图):
当客户激活一个调用的操作时,操作中指出的目标对象的对象引用经码根传递ORB核心。ORB核心代表客户自动寻找对应的服务器(即目标对象的对象实现)。找到服务器以后,ORB要确保该服务器做好接收请求的准备工作。
客户端的ORB核心接收被调用操作(或方法)的参数,并将它组码为网络可接收的格式。服务器端的ORB核心将来自网络的操作参数进行解组,然后送给服务器,并启动服务器执行所调用的操作。
执行完操作后,如有返回参数,ORB核心将它组码后传入网络。客户端ORB核心对它进行解码,并将操作结果返回客户。
CORBA工作方式静态工作方式为了更好地理解CORBA的工作方式,我们先看一个杜撰的比喻。
假设有一个国王,身边有一群所谓的学者,如哲学家、数学家、神学家等等。实际上他们并没有什么知识,唯一的法宝就是每人都有一张神奇的“名片”,能帮助他们找到真正的答案。(参阅图2.11所示的过程)。
有一天,国王突然对哲学发生了兴趣,他找来最赏识的哲学家,向他提了一个问题(见图中①)。
哲学家对这个问题一窍不通,于是他按照“名片”上的信息打了一个电话,电话通往一个遥远的国度(见图中②)。接电话的是一位哲学家的伙伴,其实他什么也不懂,但他是一位真正“先知”的私人代表,他把这个问题转达给了他的主人———那位隐居的“先知”(见图中③)。
那位先知思考后,对问题作了详尽的回答(见图中④)。
哲学家的伙伴对着话筒转达了全部的内容(见图中⑤)。
第二天,哲学家对国王宣布了这个答案(见图中⑥)。
如果把打电话改为写信,那么这个杜撰的情节几千年前就可能发生,其实,CORBA在“情节”上并不比它复杂。
那位国王就是客户(client),他的哲学家就是码根(stub),其它的“学者”们也都是码根,只不过各自对应的接口(能解决的问题)不同。国王询问哲学家,就是客户调用码根,那张神奇的“名片”就是对象引用(Object Reference),而负责通信的电话机就是ORB核心。哲学家根据名片,通过电话找到的那位哲学家伙伴就是静态框架(skeleton),而情节中那位隐居的“先知”,就是对象实现(Object Implementation)。
问题被一步步的传递,就是请求的过程,哲学家的伙伴接电话,就是接受请求的过程。先知在思考的时候,就是请求被执行的过程,答案被一步步传递,就是返回结果的过程。
在静态方式中,码根事先由IDL接口文件编译生成,它包括代理对象的定义和实现。代理对象的定义与IDL接口中的定义相一致,包括名字、操作、参数等等方面,代理对象的实现封装在代理对象内部,它实际上并没有执行客户所期待的实现,而是把客户的请求编组后交给ORB核心,等待远端的对象实现执行这一操作。执行后得到的返回参数和结果将通过ORB核心传回给码根进行解组,然后由码根以本地操作的方式把返回参数和结果送回给等待结果的客户端程序。
客户端程序通过对象引用直接调用码根中定义的各项操作。在静态方式中,框架事先由IDL接口文件编译生成,特定的框架接受特定的、对某个接口的请求。
动态工作方式假设上面杜撰的情节发生了变化,国王新聘请了一位秘书,每当遇到问题,身边又没有一位学者可以“解答”时,国王就从名片簿中挑出一张他认为可以解决这个问题的专家的名片,将它递给秘书,秘书并不宣称自己是某个问题的专家,其工作只是按照国王的旨意,根据名片的内容给对方打电话,并将获得的解答告诉国王。
这就是动态调用方式,那位全能的秘书就是DII,而存放名片信息的名片簿就是接口库。
相对静态方式而言,动态方式有以下几个优点:
灵活。动态方式允许对任意对象进行操作,所需要的只是目标对象的对象引用。此外,通过接口库的帮助,动态方式可以在运行时刻(run-time)查询对象所支持的操作的信息,对以前不知道的对象进行操作。无论是操作的对象、发起调用的参数,还是发起调用的次数等等都可以由客户程序在运行时刻视当时的环境和需要而决定。因此,动态方式相对静态方式而言灵活性大大增强。
客户程序的可移植性增强。从ORB的结构图中可以看出,DII与客户之间以及DSI与对象实现之间的接口都是标准的,无论ORB怎样实现,这部分接口应与规范规定的保持一致。由于客户和对象实现使用的是标准的接口,因此,在理论上由动态方式实现的代码应该具有良好的可移植性。
可执行程序的“体积”小。与码根和框架的方式不同,DII和DSI不需要为每个接口生成码根和框架。在现有的实现方式下,这些码根或框架都需要在编译时分别链接到使用它们的客户程序和对象实现中。而在动态方式下,无论程序中使用多少接口,所需要的只是一套支持DII和DSI的接口库,如果这个库是动态库,那么可执行程序的“体积”会更小。
然而,与静态方式相比,动态方式有以下的缺点:
使用复杂。使用静态方式时,对目标对象的操作都施加在一个本地的代理对象上,相应对象支持的所有操作及其格式都已经预先定义在这个代理对象中,因而使用方便。但是动态方式下,程序员需要自己动手“,临时”构建一个请求并发送出去,在很多情况下,程序可能还需要查询接口库以获得一个操作必要的信息,这些过程都较静态方式复杂。
速度缓慢。从功能上而言,客户端的DII与码根,服务器端的DSI与框架应完成相同的功能(发起或接受请求以及编解码),但由于静态方式下类型信息都是确定的,因此,其实现可谓“量身定做”,速度较快;而动态方式实现时,类型信息都是动态获知,速度不可避免地要慢一些。此外,程序往往要花去大量的时间来查询接口库,尤其当被查询的接口定义存放在远端的时候,这些查询还会引发远端调用,致使动态方式的速度变得更慢。
上述动态方式与静态方式的速度比较,只是定性的,其定量的比较,在很大程度上依赖于具体ORB的实现,在《Instant CORBA》一书中,作者实验的结论是,动态方式大约比静态方式慢40倍。因此,程序员在考虑采用动态方式之前,应适当平衡其对灵活性和速度的要求。通常,在客户端频繁地调用服务器对象,且服务器对象无变化的情况下,可以使用静态预编译码根的方式;而当客户端很少调用服务器对象,或者客户端在运行时发现服务器对象时,可以考虑使用动态调用方式。在同一个程序中,可以既使用动态方式,又使用静态方式,如图所示。
CORBA应用电信领域应用-TMNTMN(电信管理网),随着网络信息技术的飞速发展,网络设备日趋先进,网络业务日趋丰富,网络结构日趋复杂,这一切都需要一个智能化的网络管理系统来加以管理3。
不同的国际组织和论坛制定了许多网络管理方面的标准和规范,例如ITU-T(国际电联)制定的用于电信网络管理的TMN,IETF制定的用于Internet网络管理的SNMP协议,W3C制定的用于计算机桌面管理的WBEM,等等。TMN标准由一组协议文档组成,主要包括ITU-TX.700系列和ITU-TM.3100系列建议,它涵盖了电信管理网的体系结构、功能需求、信息模型、协议、一致性和方法学等诸多方面。它实际上是由ITU-TStudyGroup7和ISO(国际标准化组织)最早于1988年共同制定的,此后经历了多次的修订和完善。TMN不仅用于管理OSI(开放系统互联)协议,也用于管理整个网络4。