分布式软件体系结构.doc

上传人:西安人 文档编号:5018582 上传时间:2020-01-29 格式:DOC 页数:123 大小:1,012.50KB
返回 下载 相关 举报
分布式软件体系结构.doc_第1页
第1页 / 共123页
分布式软件体系结构.doc_第2页
第2页 / 共123页
分布式软件体系结构.doc_第3页
第3页 / 共123页
分布式软件体系结构.doc_第4页
第4页 / 共123页
分布式软件体系结构.doc_第5页
第5页 / 共123页
点击查看更多>>
资源描述

《分布式软件体系结构.doc》由会员分享,可在线阅读,更多相关《分布式软件体系结构.doc(123页珍藏版)》请在三一文库上搜索。

1、分布式软件体系结构编写目标:l 面向计算机专业高年级本科生与研究生的教程。l 可供从事基于Internet/Intranet的分布式软件开发人员参考使用。要求读者:l 已掌握面向对象程序设计方法与一门面向对象程序设计语言(Java最佳)。l 具备软件工程的基本知识。总体构思:l 强调理论与实践相结合:理论上以CORBA 2.4为模型,实践中以VisiBroker for Java 4.0为工具。l 强调深度与广度相结合:重点介绍CORBA的同时,兼顾DCOM与EJB两种模型,最后总结对比这三种典型体系结构的特点。主要内容:l 分布式计算的基本概念:从C/S过渡到分布式体系结构、OMA体系结构、

2、CORBA基本概念。l 分布式应用程序的开发:分布式应用程序框架、用IDL编写对象接口、编写服务程序与客户程序、部署应用程序。l 分布式计算更深入的课题:探讨分布式应用程序的可靠性、伸缩性、安全性、性能等课题可能提出的问题以及解决途径。l 不同体系结构的比较:总结CORBA、DCOM、EJB、XML等特点。l 配合教学需要的内容:在前言部分提供教学进度供参考,每一章后均配有课后练习思考题和上机实习题。- 123 -引 言分布式计算是当前软件开发技术的一个重要发展方向。C.A.R.Hoare指出:“分布式计算是一个具有重大理论与实践意义的迷人课题,其迷人之处在于理论与实践的同步发展,一方面实践推

3、动了理论,另一方面理论又指导着实践。”本书为读者介绍分布式计算领域的基本概念、开发过程、规范标准等内容。分布式计算有两种典型的应用途径。第一种应用途径是将分布式软件系统看作直接反映了现实世界中的分布性,例如当今许多业务处理流程通常呈现一种分布式运作方式,负责加工或制造的工厂可能位于珠江三角洲一带,而负责销售与市场营销的部门则可能分别位于北京、上海和广州,这时负责业务流程的软件系统也可作相应的分布式处理。第二种应用途径主要用于改进某些应用程序的运行性能,使它们比单进程的集中式实现更具有效率,此时软件系统的分布性并不是现实世界中分布性的映射,而是为充分利用额外的计算资源而人为引入的。在计算机硬件技

4、术与网络通信技术的支持下,应用需求驱使计算机软件的规模与复杂度不断增长。面对这种情况,对整个软件系统的体系结构进行分析与设计就远远重要于对算法与数据结构的选择。软件体系结构关心的正是整个软件系统的结构,它决定了一个软件系统由什么样的组件组成,以及这些组件之间的交互关系如何。典型的软件体系结构风格有设计图形用户界面常用的事件驱动风格、操作系统常用的层次化设计、设计编译程序常用的管道与过滤器风格、许多应用程序都会使用的面向对象风格等。分布式软件系统通常基于客户机服务器风格,其中客户程序提出信息或服务的请示,而服务程序提供这些信息或服务。客户机服务器计算模型的发展大约经历了三个里程碑:局域网文件服务

5、器、数据库服务器以及分布式对象。由于当前面向对象技术几乎已渗透到软件开发的每一个角落,先进的分布式软件开发方法当然离不开与面向对象技术的结合,因而分布式软件体系结构通常是客户机服务器风格与面向对象风格的有效组合,典型的例子有OMG的公共对象请求代理体系结构(CORBA)、Microsoft的分布式组件对象模型(DCOM)、Sun Microsystems的企业JavaBeans(EJB)等。在这些模型中,CORBA以其规范的严格性、供应商的无关性和其他许多先进的分布式计算特性成为我们教学的首选。在理论教学方面,我们可参考OMG发布的一系列规范和关于CORBA的丰富读物;在课程实验方面,我们既可

6、下载使用IONA Orbix、Inprise VisiBroker等商品化CORBA产品的30或60天试用版,也可使用OmniORB、TAO等免费CORBA产品。相对于其他分布式计算模型而言,CORBA在理论更为严格与完善,即使读者采用的开发平台未必是CORBA兼容的,CORBA中提出的许多问题也应加以考虑,并可借鉴CORBA提出的问题解决方案。本书从软件体系结构的角度介绍分布式软件系统分析与设计的基本概念,描述了分布式软件的开发与布署过程,并探讨分布式软件的可靠性、性能、可伸缩性等高级概念。本书的主要内容分为四个部分。第一部分“基本概念”介绍分布式计算中的基本概念与基本原理,从客户机服务器计

7、算模型过渡到真正的分布式计算模型,并掌握OMA与CORBA的基本概念。为避免为传统集中式软件的开发人员一次性引入太多分布式对象计算的新概念,我们需要一个过渡性介绍以实现循序渐进的教学目标,Java RMI以其简单性与实用性自然进入我们的视野。第二部分“开发过程”首先利用一个完整而简单的分布式应用例子程序介绍一个典型CORBA应用程序的开发过程,然后详细讨论如何利用接口定义语言(OMG IDL)编写对象接口,如何编写服务端程序与客户端程序,以及如何部署最终的应用程序。第三部分“高级课题”探讨分布式应用程序中的高级课题,提出可能产生的问题以及这些问题的可能解决途径,包括分布式环境下对象查找、如何提

8、高分布式应用程序的可靠性、如何提高服务端程序的可伸缩性等。第四部分“其他与展望”通过简介与对比其他分布式体系结构(如DCOM、EJB、XML等)拓宽读者在分布式计算领域的知识面,探讨分布式计算进一步的发展方向。本书可供从事基于InternetIntranet的分布式软件开发人员参考使用,也可作为计算机专业高年级本科生与研究生学习分布式计算课程的教材。本书假设读者已掌握面向对象程序设计方法与Java语言,并具备面向对象软件工程的基本知识。如果选用本书作为授课教材,对具有面向对象程序设计基础并熟练掌握C+和Java语言的学生宜讲授60课内学时,安排课外实验36学时,教学进度安排可参考如下(括号中分

9、别标明了课内学时数与课外实验学时数):第1章(66)、第2章(40)、第3章(46)、第4章(40)、第5章(86)、第6章(66)、第7章(20)、第8章(20)、第9章(40)、第10章(60)、第11章(66)、第12章(46),第四部分的第13至15章(40)。对于不熟悉Java语言和Web应用的学生宜讲授80课内学时,安排课外实验40学时。本书课后练习中规模较大或复杂性较高的题目以星号“*”标出,这些题目适合作为课程设计的选题。在即将由ACMIEEE-CS修订发布的计算教学大纲2001(CC2001)中,“以网络为中心的计算(NC)”已成为14个知识领域之一,其中包含客户机服务器计算

10、、开发Web应用、通信与网络、分布式对象系统、协作技术与群件等专题。本书内容覆盖了该知识领域的许多专题。本书中所有例子程序均使用Inprise公司的VisiBroker for Java 4.0和WebGain公司的VisualCaf Enterprise Edition 4.0平台开发,这些例子很容易移植到其他开发平台。读者可从我们的教学网站http:/下载这些例子程序的全部源代码。分布式软件系统是软件开发的一个新兴领域,并且各种分布式计算模型还在不断地迅速发展。由于作者水平有限,书中谬误之处在所难免,恳请广大读者不吝批评指正。李文军()周晓聪()李师贤()2001年5月于广州康乐园第一部分

11、 基本概念第 1 章 客户机服务器体系结构本章利用Java语言的远程方法调用RMI与数据库接口JDBC开发一个简单的电话计费查询分布式应用程序,通过这个完整的例子帮助读者复习客户机服务器体系结构的基本概念,并分析与探讨该应用程序需要进一步考虑与改进的不足之处,从而引出分布式软件体系结构要解决的问题。 1.1 软件设计的基本概念 1.1.1 隐式地 vs 显式地隐式地(implicitly)与显式地(explicitily)是软件开发技术中经常出现的两个修饰术语,用于表示程序设计语言、编程工具或软件开发环境等对软件开发人员的两种不同支持方式。例如一个采用面向对象方法完成的设计同样也可以利用C语言

12、实现,然而C语言对面向对象设计的支持是一种隐式的方式,面向对象设计的许多概念在C语言中无法直接地表达出来,显然这种隐式支持远远比不上C+、Java、Ada、Eiffel、Smalltalk等面向对象程序设计语言提供的显式支持。软件开发人员获得显式支持的本质可看作是将许多原来必须由程序员动手实现的任务交由更底层的编译程序、开发工具或运行环境完成。例如在数据库管理系统的帮助下,应用程序员开发数据处理应用程序时减轻了许多数据定义、查询、完整性、安全性等方面的负担。程序设计技术或软件开发技术的发展方向之一是不断为软件开发人员提供更完善、更有效的显式支持。例如在C语言或Pascal语言中无法显式地描述一

13、个求平方根函数square_root()中可能引发的异常(譬如计算对象是一个负数),而C+语言或Java语言允许在函数原型中显式地将函数体可能引发的异常表达出来,这种显式表达使得编译程序可帮助程序员检查该函数体中是否真的可能引发这些异常,以及约束使用这些函数的程序必须处理哪些异常。此外,将异常作为函数原型的一部分也有助于使用函数的程序员更全面地理解这些函数的语法与语义。又如在面向对象程序设计中一个实体除了属性与行为外,还应包含该实体的属性与行为应满足的约束。譬如一个银行帐户ACCOUNT除了拥有帐户标识、存款余额等属性以及存款、取款、查询余额等行为之外,还至少必须满足一个约束,即在帐户生存期的

14、任一时刻存款余额不得小于0(如果是允许透支的信用卡帐户,则应将约束修改为透支不得超过某一上限,而透支上限必须是帐户的一个属性)。在C+语言或Java语言中,程序员无法将这一约束显式地表达出来,只能在对象初始化、存款、取款等行为的实现中隐式地表达,使用这些组件的其他程序员也只能通过理解这些行为的实现才能了解到ACCOUNT的这种约束。当然通过注释将约束表达出来是一种良好的程序设计风格,但编译程序不能为此提供任何帮助。相比之下,Eiffel程序员可显式地描述ACCOUNT必须满足的约束,以及每一操作之前或之后必须满足的条件,程序员不必再考虑正常条件之外的异常,而交由运行环境负责引发相应的异常。在分

15、布式软件开发中比传统的集中式软件开发有更多的问题需要解决,程序员可以自己动手解决这些问题,但更理想的情况是由底层的支持(如语言、工具、环境等)帮助程序员完成这些任务。本书着重讨论在分布式软件开发中需要解决的重要问题,以及当前的分布式软件开发规范与产品对解决这些问题提供的支持。随着分布式软件开发技术的发展与成熟,程序员将获得越来越完善与有效的支持。对显式支持与隐式支持的讨论可以提醒我们,必须留意在分布式软件开发中存在哪些问题需要解决,这些问题并不会因为得不到显式支持而消失,在只有隐式支持的情况下程序员仍要自行解决这些问题。因而对解决关键问题的显式支持是评价与选择分布式软件的体系结构规范、程序设计

16、语言、开发工具与环境的一个重要因素。当然更重要的一点是提醒我们,在软件开发过程中应考虑可为分布式软件开发添加哪些新的显式支持,从而为分布式软件在我国的推广应用作出自己的贡献。 1.1.2 逻辑的 vs 物理的逻辑的(logical)与物理的(physical)分别代表着两个不同的抽象层次。早在10年前由IEEE-CS/ACM联合制订的91计算教学计划中,就将抽象层次列为计算机科学与工程专业学生必须掌握的一个核心概念,这一概念贯穿了计算机学科的众多领域。抽象是人类认知世界的最基本思维方式之一。罗素曾断言:“发现一对鸡、两昼夜都是数的实例,一定需要很多年代,其中所包含的抽象程度确实不易达到;至于是

17、一个数的发现,也必定很困难。”抽象源于人类自身控制复杂性能力的不足:我们无法同时把握太多的细节,复杂的问题迫使我们将一些相关的概念组织成不同的抽象层次。例如日常生活中的is-a关系是人们对概念进行抽象和分类的结果,例如苹果是一种水果,水果是一种植物等,生物学采用的界、门、纲、目、科、属、种标准生物分类方法是这一思维方式的经典应用。将这种is-a关系在程序中显式地表达出来而形成的继承机制,是面向对象程序设计最重要的特征之一。 在软件设计中太容易找到抽象层次的实例,例如变量类型、对象类抽象数据类型、实现规格说明、数据流图分解与平衡等。逻辑层与物理层组织是一种常见的抽象层次。一个典型的C+程序从逻辑

18、上看由m个类与1个主函数main()组成,但同样的逻辑组织形式却在物理上可根据不同需要组织为不同形式的文件模块,整个程序既可能划分为n1个文件模块,也可能划分为n2个文件模块。从不同的抽象层次来看,这两个程序的物理组织形式虽然不同,但其逻辑组织形式却是一样的。又如在管理信息系统的开发过程中,系统分析的主要任务是根据现有管理信息系统的物理模型建立更高抽象层次的逻辑模型,在逻辑模型中抛弃了物理模型中那些开发者不关心的细节,仅表达了系统边界之内用户最关心的内容,这一建模过程的本质就是一个抽象过程。系统分析员通过对逻辑模型的研究与改进,进一步实现在计算机平台上的一个新的物理模型。在分布式软件系统中,有

19、许多机制虽然与传统的集中式软件在物理层次表现出很大差异,但从逻辑层次上看它们却是统一的,例如普通函数调用与远程过程调用(RPC)、对象消息传递与远程方法调用(RMI)、接口与实现的分离、同一接口多种实现等。因而在分布式软件体系结构的学习与研究中,利用不同的抽象层次可帮助我们从更高层次掌握分布式软件系统的各种机制,并且可以用一种统一的知识框架来理解分布式软件与传统的集中式软件的基本概念、表示技术以及开发过程。同理,一个软件系统在逻辑层次表现为分布式的,但在物理层次部署时却可能是集中式的。对于同一个分布式软件系统,可以用一台单机同时充当客户机与服务器,并包含了两者之间的通信,从而让我们有可能在家中

20、的一台电脑上就能学习开发与调试分布式应用程序,然后再将这些应用程序部署到真正的分布式运行环境中。 1.1.3 面向对象技术在二十世纪80年代兴起的面向对象技术已在软件生存期的各个阶段取代传统的结构化方法,成为当前软件开发的主流技术。在分布式软件开发领域也不例外。面向对象开发过程本质上是一个建模过程。开发人员通过分析问题域中实体的属性、行为、约束等,抽象出能描述这些实体共同结构与特征的概念,然后在计算机中利用类建立这些概念的系统模型,再通过类创建具体的对象实例模拟问题域的实体行为。面向对象开发方法强调将系统功能建立在系统模型之上,所有系统功能采用底层的系统模型提供的术语来表达,从而提高了软件系统

21、的可扩展性与可维护性。除了封装与信息隐藏、数据抽象、模块化等特征外,面向对象技术的最主要特色是继承与多态性。继承是日常生活中的is-a关系在程序中的显式表达,是重用数据与操作的重要手段。多态性有十分广泛的含义,这里主要是指运行期间程序表现出来的多态性,它建立在继承与动态绑定的基础上,使得一个对象可以具有多种不同的动态类型,从而大大提高了面向对象程序的表达能力。先进的分布式软件体系结构必须与面向对象技术结合在一起,从而可分享面向对象技术带来的众多好处。例如由开放软件基金会(OSF)于1992年发布的分布式计算环境(Distributed Computing Environment,缩写为DCE)

22、采用的是远程过程调用(Remote Procedure Call,缩写为RPC)技术,RPC支持开发人员进行结构化程序设计,使得客户程序可以像调用本地过程一样调用服务程序中的过程。而由Sun Microsystems于1996年发布的远程方法调用(Remote Method Invocation,缩写为RMI)技术是一种分布式对象模型,保持了Java语言的对象语义,支持分布式应用程序员进行面向对象程序设计,在客户程序中可以像将消息传递给本地对象一样,将消息传递给服务程序中的对象。当前几种主流的分布式软件体系结构均融合了分布式计算与面向对象技术,包括OMG的公共对象请求代理体系结构(CORBA)

23、、Microsoft的分布式组件对象模型(DCOM)、Sun Microsystems的企业版JavaBeans(EJB)等。 1.1.4 软件体系结构随着计算机软件系统的规模不断增大并且系统复杂度不断提高,在软件开发过程中对整个软件系统的体系结构进行分析与设计远比对算法与数据结构的选择更加重要。软件体系结构关心的正是整个软件系统的结构,它决定一个软件系统由什么样的组件构成,以及这些组件之间的交互关系如何,并提供一种模式指导组件的合成。尽管严格的形式化工作仍处于实验阶段,软件体系结构在软件工程中已扮演着越来越重要的角色。典型的软件体系结构风格有设计图形用户界面(GUI)常用的事件驱动风格、设计

24、操作系统常用的层次化设计风格、设计编译程序常用的管道与过滤器风格、设计分布式应用程序常用的客户机服务器风格等。一个实用的软件系统通常是几种典型体系结构风格的组合。分布式软件系统通常基于客户机服务器(client/server)模型,因而组成系统的最核心组件是客户程序与服务程序,然而不同的分布式软件体系结构还决定了各自不同的组件以及这些组件之间的交互方式。例如在OMG的CORBA模型中,存在若干称为对象请求代理(ORB)的组件,这些组件之间采用因特网ORB间协议(IIOP)进行通信;又如在OSF/DCE中,客户程序与服务程序之间通过远程过程调用(RPC)进行交互,参数与返回值的编码采用外部数据表

25、示(XDR)技术,而Sun Microsystems的EJB则利用远程方法调用(RMI)进行交互,参数与返回值的编码采用Java语言专用的对象串行化技术。本书主要从软件体系结构的角度探讨分布式软件系统的有关课题。一个分布式应用系统在软件体系结构层次需要考虑的问题包括如何将组件合成系统、如何将功能指派到设计元素、通信与同步协议、全局控制结构、物理的分布、可伸缩性与可靠性等。 1.2 客户机服务器模型 1.2.1 客户机与服务器在二十世纪90年代兴起的客户机服务器数据库技术是自70年代关系数据库技术以来数据库技术的一次重大飞跃。由于在客户机服务器数据库系统中将系统的处理任务划分为客户系统与数据库服

26、务器两端,因而大量的数据库操作可在后端运行,工作站只需能够运行前端软件即可。尽管客户机服务器系统比传统的集中式系统更复杂,然而这一新的计算模型带来的优势是显而易见的,例如减轻了网络传输负担,实现了工作站无关性,更方便维护数据的完整性等。其实客户机服务器体系结构并不仅仅局限于数据库应用,这种计算模型有着更广义的定义。如果一个系统被划分为两类不同的但相互联系的组成部分,其中一方提出对信息或服务的请求(称为客户机),而另一方提供这种信息或服务(称为服务器),那么这种体系结构即可看作是一种客户机服务器计算模型。按照这一定义,局域网中的工作站与文件服务器之间是一种客户机服务器模型,其中工作站向文件服务器

27、发送服务请求,例如要求访问文件或网络打印等,文件服务器接收这些请求后为工作站提供这些服务。因特网的许多应用程序都采用客户机服务器模型,例如Web浏览器与服务器、电子邮件客户程序与服务程序、FTP客户程序与服务程序等。客户机与服务器是一个相对的概念,一个服务器可能是另一个服务器的客户机,一个客户机也可能是另一个客户机的服务器。客户机与服务器的划分可以是物理层次的,例如局域网中的工作站与文件服务器通常是由两台不同的计算机系统担任;客户机与服务器的划分也可以是逻辑层次的,这时我们经常又将这两端分别称为客户程序与服务程序。一个常见的简单例子是在过程式程序设计中,执行函数调用表达式的子程序与实现函数体的

28、子程序可看作一种客户机服务器模型,其中函数实现方是服务程序,函数调用方是客户程序。在面向对象程序设计中,消息传递可看作客户程序向服务程序发送服务请求的过程,发送消息的是客户程序,接收并处理消息的服务程序。在普通的函数调用中,对于函数实现与函数调用双方最为重要的是两者之间的接口(又称界面,即函数原型说明)以及通信协议(例如双方对调用风格的约定,决定采用C还是Pascal的调用风格)。客户程序与服务程序之间的接口描述越清晰,对编写客户程序与服务程序的开发人员帮助越大,同时各种编程工具或可重用组件管理工具越有可能为开发人员提供有力支持。函数原型一般都包含了函数名字、返回值类型、参数个数与类型等,更完

29、善的接口还可能包括可能引发的异常、必须满足的前置条件与后置条件等。这些接口的内容都是语法层面的,如果有朝一日能提供语义层面的接口描述,软件开发人员将看到软件构造自动化的曙光,这当然还要依赖于形式语义学研究有进一步的突破。分布式软件系统绝大多数采用客户机服务器体系结构,其中最重要的仍是上述接口与通信协议的问题,只不过由于客户端与服务端在物理层次上的分离,导致通信协议更加复杂,并且可靠性、安全性、性能等因素显得更加突出。 1.2.2 客户端与服务端的分离分布式软件与传统的集中式软件主要区别在于强调客户端与服务端在地理位置上的分离。虽然分布式软件与集中式软件在逻辑层次有许多方面是一致的,但在物理层次

30、两者仍有许多重大区别。在分布式软件系统中客户端与服务端的物理分离可带来许多好处。首先,整个系统的所有计算任务可在客户端与服务端两边进行负载重新分布,使得RISC工作站与微机建立的计算机网络系统可以完成以前只有价格昂贵的大型机(mainframe)才可胜任的工作,实现企业计算规模的下行(downsizing);而与传统的基于局域网的应用系统相比,客户端与服务端的分离大大减少了网络传输的数据量,可有效地提高系统的运行效率,实现企业计算规模的上行(upsizing)。其次,这种新的计算模型更好地支持了平台无关性,客户端既可以运行在IBM PC兼容微机、Macintosh微机、RISC工作站等不同机型

31、,也可以运行Microsoft Windows、IBM OS/2、Apple System 8、各种版本的Unix等不同操作系统,还支持TCP/IC、IPX/SPX、NetBEUI等不同网络协议。此外,采用客户机服务器计算模型的软件系统具有更好的可扩充性,例如可在服务端功能不变的前提下对服务端程序进行改进或扩充,而这种改进与扩充不会影响到客户端的应用程序。当然这种分离也会带来一些新问题,对于软件开发人员而言,最主要的问题是分布式软件系统通常比集中式软件系统更加复杂。例如开发人员不得不分别开发客户端与服务端的应用程序,并力求保持两端应用程序的一致性,软件系统的部署与维护也更加困难。此外,设计分布

32、式软件系统时比设计集中式软件系统需要考虑更多的可靠性、安全性、性能等软件质量要素。本书将主要讨论客户机服务器体系结构设计中的这些复杂问题,包括如何更好地显式表达客户端与服务端双方的公共接口,客户端应用程序与服务端应用程序双方如何进行通信,客户端应用程序如何查找服务程序,如何保证服务端应用程序的可用性等等。 1.2.3 两层模型与多层模型典型的客户机服务器体系结构又称为两层(2-tier)模型。在两层模型的设计中,由客户应用程序直接处理对数据库的访问。因而每一台运行客户应用程序的客户机都必须安装数据库驱动程序,增加了系统安装与维护的工作量。同时,数据库由众多客户程序直接访问,导致数据的完整性与安

33、全性难以维护。为提高数据的安全性与系统的可扩充性,可在两层模型的基础上考虑采用三层(3-tier)或多层(N-tier)设计模型,将数据库访问分布在一个或多个中间层。客户程序与数据库的连接被中间层屏蔽,客户程序只能通过中间层间接地访问数据库。中间层可能运行在不同于客户机的其他机器上,经过合理的任务划分与物理部署后,可使得整个系统的工作负载更趋均衡,从而提高整个系统的运行效率。这些位于中间层的中间件(middleware)又称应用服务程序(application server),因为它们实际上表达了一个企业处理信息的主要业务逻辑(business logic),即企业的系统模型与功能模型,而客户

34、程序仅实现图形用户界面,完成终端用户与业务逻辑之间的交互。从客户程序的角度来看,中间件将企业的所有业务逻辑抽象为更高层次的应用程序接口(API),客户程序则通过这些API构建整个企业的应用系统。与典型的两层模型相比,三层模型或多层模型可更好地支持对企业业务逻辑的集中控制与管理。 1.3 一个简单的例子 1.3.1 问题背景电信收费是当前老百姓关心的热点问题,明明白白消费是每一个消费者的合理要求,但如果打印并邮寄每月话费清单无疑会额外花费大量的人力、物力与财力。随着我国信息基础设施的不断完善,上网普及率越来越高,通过因特网查询话费将是一条非常可行的途径。本小节以一个简化的电话计费查询程序为例,向

35、读者介绍分布式应用程序的基本概念,并通过对这一简单应用程序的讨论引出分布式软件体系结构中需要考虑的更高级课题。该例子程序采用纯Java语言编写,利用JDBC/ODBC访问关系数据库,并采用远程方法调用RMI实现客户程序与服务程序之间的交互。客户程序只能通过服务程序间接地访问关系数据库,因而该例子程序属于一种典型的三层设计模型。 1.3.2 数据库设计根据数据库设计原理,我们很容易得到如图1.1所示的典型设计结果。 数据库Telephone 表TelephoneDirectorynumber文本类型;电话号码subscriber文本类型;电话用户姓名 表CallHistorynumber文本类型

36、;电话号码(索引,允许重复)startTime日期/时间类型;起始通话时间endTime日期/时间类型;终止通话时间图1.1 话费查询程序中的数据库设计其中,表TelephoneDirectory记录了所有用户的电话号码,以number为主关键码;表CallHistory记录了所有电话的通话历史,其中number是外部关键码,建立该属性的允许重复的索引。表CallHistory通过外部关键码number与表TelephoneDirectory相关联。由于同一名字的用户可能登记多个电话号码(例如一个用户同时拥有两部住宅电话和一部移动电话),因而电话计费查询程序除了提供根据电话号码查询话费清单外,

37、还可能提供以用户名字进行查询。本例子程序演示了后者的用法。程序中利用JDBC/ODBC访问数据库,因而支持使用多种不同的数据库管理系统,只要这些数据库管理系统提供了ODBC接口,如Microsoft Access、Microsoft SQL Server、Sybase、Oracle等。使用ODBC访问数据库之前,必须将数据库配置为ODBC的一个数据源。假设我们选用了Microsoft Access数据库,则这一安装步骤为:在Windows 98的控制面板中打开“ODBC数据源(32位)”,单击“添加”按钮后选择一个驱动程序(此处应为“Microsoft Access Driver (*.mdb

38、)”),然后为数据源命名并选择相关联的Access数据库文件,如图1.2所示。图1.2 在Windows 98中添加ODBC数据源为进一步提高程序的数据独立性,还可以利用许多关系型数据库管理系统支持的“存储过程”来完成数据查询与更新操作。数据独立性使得在数据库中表的属性或表之间的关联发生某些变化时,程序员无需对应用程序作任何修改。使用存储过程访问数据库还可带来其他好处,例如提高了SQL语句查询与更新数据库的效率,在网络环境下加强了数据库的安全性等等。在不同的数据库管理系统中,存储过程可能有不同的名字,如保留过程、触发器、查询等。图1.3展示了在Microsoft Access中编写的一个存储过

39、程(即一个查询),它根据指定电话用户名字的参数(Telephone Subscriber)查询该用户登记的所有电话的通话记录。本节的例子程序利用该存储过程实现对数据的查询。 查询QueryCallHistoryWithSubscriberSELECT TelephoneDirectory.number, CallHistory.startTime, CallHistory.endTimeFROM TelephoneDirectory, CallHistoryWHERE(TelephoneDirectory.number = CallHistory.number) AND (TelephoneD

40、irectory.subscriber = Telephone Subscriber)ORDER BY startTime;图1.3 根据用户名字查询通话记录的存储过程 1.3.3 客户程序与服务程序之间的通信客户程序与服务程序之间需要通信以交换信息。在本小节的例子程序中,服务程序负责接收客户程序发来的查询请求,完成访问数据库的查询操作,并将查询结果返回给客户程序。客户程序利用图形用户界面与终端用户进行交互,从终端用户获取电话用户的名字并作为参数向服务程序发出查询请求,然后将服务程序返回的查询结果显示给终端用户浏览。客户程序与服务程序可利用socket进行通信,socket在TCP/IP网络中

41、是一种很原始、高效率的通信方式,但要求客户程序与服务程序自己处理交换消息的编码与解码工作,即程序员必须自定义客户程序与服务程序之间的应用层通信协议,这不仅需要花费大量的编程时间(例如必须考虑连接控制、错误恢复、如何通过防火墙等问题),同时也比较容易产生错误。一种更好的通信方式是使用远程过程调用(RPC),它将客户程序与服务程序之间的通信接口抽象为过程调用层次,程序员可像调用本地过程一样去调用远程过程,由RPC系统完成参数与返回值的打包、解包与传输等底层任务。但使用RPC不能平滑地与面向对象技术结合在一起。本小节的例子程序采用了抽象层次更高的远程方法调用(RMI)。RMI是支持多层分布式对象计算

42、的一系列Java类,使得Java应用程序员无需额外的程序设计工作即可实现客户程序与服务程序之间的连接与通信,在客户程序中可以像使用本地对象一样调用服务程序中远程对象的方法。 1.3.4 远程方法调用RMI可看作一种简化的、专用于Java平台的CORBA模型,由JDK 1.1开始支持。RMI的服务程序通常是一个Java应用程序,而客户程序既可以是一个Java应用程序,也可以是一个Java Applet。RMI注册表rmiregistry是运行在服务器上的一个后台进程,必须在服务程序启动之前就已启动完毕,它相当于客户程序与服务程序之间的通信网关。服务程序将远程对象的名字注册到RMI注册表,客户程序

43、通过RMI注册表将远程对象名字解析为远程对象引用,通过该对象引用调用远程对象上的方法。RMI体系结构采用典型的层次设计风格,从上至下分别由桩框架层、远程引用层和传输层组成,各层之间明确定义了接口与协议,如图1.4所示。应用程序 客户程序 服务程序RMI系统桩 框 架远 程 引 用 层传 输 层图1.4 远程方法调用(RMI)体系结构RMI系统采用类似CORBA的请求代理机制,桩(stub)是远程对象在客户端的代理,客户程序中的远程对象引用实际上是对本地桩的引用。桩负责将远程调用请求通过远程引用层转发给服务端的框架(skeleton),再由服务端的框架分派给真正的远程对象实现。创建应用程序时,客

44、户程序与服务程序都需要桩,而框架仅服务程序需要。远程引用层完成调用的语义,例如决定服务程序的对象是单个对象,还是需要与多个位置进行通信的复制对象,这些语义由远程对象的实现提供。远程引用层还为上一层屏蔽了服务程序的激活方式,即桩框架层不必关心提供远程对象的服务程序是一直在同一机器上运行,还是仅在有方法调用时才被激活(JDK 1.2开始支持不同的激活策略)。传输层负责建立与管理连接,跟踪远程对象,以及将调用请求分派给合适对象。在服务端,传输层将调用请求向上转发给远程引用层,远程引用层作相应处理后转发给框架,由框架向上调用远程对象的实现,由远程对象的实现完成真正的方法调用。远程调用的返回值送回客户端

45、的路线是:首先经过服务端的框架、远程引用层和传输层,再向上经过客户端的传输层、远程引用层和桩。RMI在桩框架层利用了两种关键技术。首先,Java语言专用的对象串行化技术可将对象透明地传送到不同地址空间,桩与框架利用对象串行化技术打包(marshal)与解包(unmarshal)远程调用的参数与返回值。其次,动态类装载技术用于支持将客户端的桩作为远程对象本身,桩实现了相同的远程接口集合,从而支持Java语言的类型检查与类型转换机制。 1.3.5 接口定义一个基于RMI的多层模型分布式应用程序通常包括以下几部分:远程接口,规定了客户程序与服务程序进行交互的界面;远程对象实现,为远程接口规定的每一个

46、方法提供真正的实现;服务程序,远程对象并不是服务程序本身,它需要由服务程序创建并注册,服务程序中的这些真正提供服务的对象实例又称伺服对象(servant);客户程序,利用服务程序中伺服对象提供的服务完成某一功能。其中,远程接口是编写服务程序与客户程序之前需要首先考虑的问题。Java提供了接口与类两种机制:接口不含数据表示方法与操作的具体实现,因而适用于定义对象的规格说明(specification),一个接口可以同时继承多个接口;类给出了数据表示方法与操作实现,因而适用于定义对象的实现(implementation),仅支持对类的单继承。所有远程对象的接口都使用接口来定义,并且必须继承java

47、.rmi.Remote接口,还要求其中的每一个方法必须声明抛出java.rmi.RemoteException异常,因为网络通信或服务程序等原因均可能导致远程调用失败。程序1-1给出了例子程序中通话记录管理器的远程接口定义。程序1-1 CallManagerInterface.java/ 通话记录管理器CallManager的远程接口package Telephone;public interface CallManagerInterface extends java.rmi.Remote / 根据电话用户名字查询通话记录。 / 参数: subscriber - 电话用户的名字 public

48、Database.DatabaseTableModel getCallHistory(String subscriber) throws java.rmi.RemoteException; 1.3.6 服务端程序程序1-2定义的类CallManager为远程接口CallManagerInterface中的每一个远程方法提供了具体实现。为防止多个客户程序并发地调用数据库查询操作,方法getCallHistory()被定义为同步方法。程序1-3所示ServerApplication是服务程序的主程序,它必须首先装入安全管理器,用于保证动态装载的类不会执行某些敏感操作,如果未指定安全管理器则不允许装入任何RMI类。程序1-2 CallManager.java

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 研究报告 > 商业贸易


经营许可证编号:宁ICP备18001539号-1