跨平台跨语言的分布式开发框架ICE

来源:互联网 发布:网络安全技术有哪几类 编辑:程序博客网 时间:2024/06/05 14:14

ICE简介:

ICE(The Internet Communications Engine:互联网通信引擎)是ZEROC的开源通信协议产品,是一个面向对象的中间件,使我们能够以最小的代价构建分布式应用程序。

ICE跨平台、跨语言,这使我们可以更专注于业务逻辑的开发,它来处理所有底层的网络接口编程,这样我们就不用去考虑这样的细节:打开网络连接、网络数据传输的序列化与反序列化、连接失败的尝试次数等。

ICE和WEB SERVICE都是分布式应用的解决方案,但WEB SERVICE最要命的缺点就是他的性能问题,对于要求比较高的行业是很少会考虑WEB SERVICE的。

个人觉得ICE在理论上可以替代JNI(将Server和Client端都部署到本地,通过本地网络连接)。

ICE的工作方式:

Ice 是一种面向对象的中间件平台,这意味着 Ice为构建面向对象的客户-服务器应用提供了工具、API 和库支持。要与Ice持有的对象进行通信,客户端必须持有这个对象的代理(与CORBA的引用是相同的意思),这里的代理指的是这个对象的实例,ICE在运行时会定位到这个对象,然后寻找或激活它,再把In参数传给远程对象,再通过Out参数获取返回结果。

这里提到的代理又分为直接代理和间接代理,直接代理其内部保存有某个对象的标识,以及它的服务器的运行地址;间接代理指的是其内部保存有某个对象的标识,以及对象适配器名(object adapter name),间接代理没有包含寻址信息,为了正确地定位服务器,客户端在运行时会使用代理内部的对象适配器名,将其传给某个定位器服务,比如IcePack服务,然后,定位器会把适配器名当作关键字,在含有服务器地址的表中进行查找,把当前的服务器地址返回给客户,客户端run time现在知道了怎样联系服务器,就会像平常一样分派 (dispatch)客户请求。

ICE可以保证在任何的网络环境或者操作系统下,成功的调用只有一次,它在运行时会尽力的定位到远程服务器,在连接失败的情况下会做尝试性重复性连接,确实连不上的情况会给用户以提示。

客户端在调用服务端的方法时,可以采取同步或异步的方式实现,同步调用就相当于调用自己本地的方法一样,其它行为会被阻塞;异步调用是非常有用的调用方式,如服务端需要准备的数据来自于其它异步接口,这个时候客户端就不需要等待,待服务端数据准备充份后,以消息的方式通知客户端,服务端就可以去干其它的事情了,而客户端也可以到服务端获取数据了。

ICE的调用模式:

ICE采用的网络协议有TCP、UDP以及SSL三 种,不同于WebService,ICE在调用模式上有好几种选择方案,并且每种方案正对不同的网络协议的特性做了相应的选择。

Oneway(单向调用):客户端只需将调用注册到本地传输缓冲区(Local Transport Buffers)后就立即返回,不会等待调用结果的返回,不对调用结果负责。

Twoway(双向调用):最通用的模式,同步方法调用模式,只能用TCP或SSL协议。

Datagram(数据报):类似于Oneway调用,不同的是 Datagram调用只能采用UDP协议而且只能调用无返回值和无输出参数的方法。

BatchOneway(批量单向调用):先将调用存 在调用缓冲区里面,到达一定限额后自动批量发送所有请求(也可手动刷除缓冲区)。

BatchDatagram(批量数据报):与上类似。

不同的调用模式其实对应着不动的业务,对于大部分的有返回值的或需要实时响应的方法,我们可能都采用Twoway方式调用,对于一些无需返回值或 者不依赖返回值的业务,我们可以用Oneway或者BatchOneway方式,例如消息通知;剩下的Datagram和BatchDatagram方式 一般用在无返回值且不做可靠性检查的业务上,例如日志。

客户端与服务端的结构:

这个图示显示了使用ICE做为中间件平台,客户端及服务端的应用都是由应用代码及ICE的库代码混合组成的。

客户应用及服务器应用分别对应用的是客户端与服务端。

代理是根据SLICE定义的ice文件实现,它提供了一个向下调用的接口,提供了数据的序列化与反序化。

ICE的核心部份,提供了客户端与服务端的网络连接等核心通信功能,以及其它的网络通信功能的实现及可能的问题的处理,让我们在编写应用代码的时候不必要去关注这一块,而专注于应用功能的实现。

ICE的简单示例:

准备一个ice文件并命名为:Printer.ice。

执行slice2java Printer.ice,会生成一些JAVA文件,如下图示:

这些文件的类图结构:

    这里对生成的一些文件做些解释,分成两部份,服务端类文件及客户端类文件:

• <interface-name>.java:这个源文件声明在ICE文件中定的接口名称的Java接口,如这里是Printer。

• _<interface-name>Operations.java、_<interface-name>OperationsNC.java:这是两个定义操作的接口文件,每个接口文件中定义了一个操作实现,定义的操作与Slice接口中定义的操作相一致,只是在_<interface-name>Operations.java中定义的方法多了一个参数"Ice.Current __current",这个参数的作用是可以允许我们访问 "正在执行的请求"和 "服务器中的操作的实现"等信息,也就是我们的请求需求需要其它请求的支持时或者要获取其它请求的执行结果时,我们可以调用这个方法,这两个接口文件都会被接口文件_<interface-name>.java继承。

• _<interface-name>Disp.java:这个文件包含的是服务器端骨架类的定义,所用接口定义都要继承这个东西,这里的接口指供客户端调用的接口。

• <interface-name>PrxHolder.java:代理定义holder 类,是对应Out参数使用的。一般参数都是值传递,这个类的作用是使参数通过引用传递。ICE框架应用了很多反射机制,这个类是改变远程参数的一个映射。

• _<interface-name>Del.java、_<interface-name>DelD.java、_<interface-name>DelM.java:不用关心上面的这些文件,这些文件包含的是供Java 映射内部使用的代码;它们包含的功能与应用程序无关。

• <interface-name>Prx.java :这个是代理接口。例如PrinterPrx,在客户的地址空间中, PrinterPrx 的实例是"远地的服务器中的Printer接口的实例"的"本地大使"。与服务器端对象有关的所有细节,比如其地址、所用协议、对象标识,都封装在该实例中。

注意, PrinterPrx 继承自Ice.ObjectPrx。这反映了这样一个事实:所有的Ice 接口都隐式地继承自Ice::Object。说的更明白些,就是这个类的方法调用都是远程服务端的调用,执行printString()方法的具体实现是在远程服务端执行的。

• <interface-name>PrxHelper.java:这个是接口的代理定义助手类,就是帮你获得代理类的。经常用的就两个方法checkedCast和uncheckedCast。这两个方法实现的都是向下转换。

注意, checkedCast会联系服务器。这是必要的,因为只有服务器情况中的代理实现确切地知道某个对象的类型。所以,checkedCast可能会抛出ConnectTimeoutException或ObjectNotExistException(这也解释了为何需要助手类:ICE在运行时必须联系服务器,所以我们不能使用Java 的强制转换)。与此相反,uncheckedCast不会联系服务器,而是会无条件地返回具有所请求的类型的代理 。但是,如果你要使用uncheckedCast,你必须确定这个代理真的支持你想要转换到的类型;而如果你弄错了,你很可能会在调用代理上的操作时,引发运行时异常。对于这样的类型失配,最后可能会引发OperationNotExistException,但也有可能引发其他异常,比如整编异常。而且,如果对象碰巧有一个同名的操作,但参数类型不同,则有可能根本不产生异常,你最后就会把调用发送给类型错误的对象;这个对象可能会做出非常糟糕的事情。

ICE的优点:

ICE的效率较高,因为他本身的传输机制都是基于二进制;

支持同步和异步的消息传递;

支持多个接口;

机器无关性,客户及服务器与底层的机器架构屏蔽开来。对于应用代码而言,像字节序和填充这样的问题都隐藏了起来;

语言无关性,客户和服务器可以分别部署,所用语言也可以不同;

实现无关性,客户不知道服务器是怎样实现其对象的。这意味着,在客户部署之后,服务器的实现可以改变;

操作系统无关性,Ice API 完全是可移植的,所以同样的源码能够在 Windows和 UNIX上编译和运行;

线程支持,Ice run time 完全是线程化的,其 API 是线程安全的,作为应用开发者,(除了在访问共享数据时进行同步)无需为开发线程化的高性能客户和服务器付出额外努力。

传输机制无关性,Ice 目前采用了TCP/IP 和 UDP作为传输协议。客户和服务器代码都不需要了解底层的传输机制;

位置和服务器透明性,Ice run time 会负责定位对象,并管理底层的传输机制,比如打开和关闭连接;

安全性,通过 SSL强加密,可以使客户和服务器完全安全地进行通信,这样,应用可以使用不安全的网络安全地进行通信,你可以使用 Glacier穿过防火墙,实现安全的请求转发,并且完全支持回调;

内建的持久机制,使用 Freeze,创建持久的对象实现变成了一件很容易的事情,Ice提供了对高性能数据库 Berkeley DB[18] 的内建支持;

开放源码。

后记:

这里只是简单的对ICE进行介绍,还有很多东西没有提到,如ICE的语法规则、ICE的版本控制(Facet)、持久化 (Feeze)、服务装箱管理 (ICEBox)、文件分发(ICEPatch2)、发布/订阅 服务(ICEStorm)、网络拓扑负载解决方案--终极武器(ICEGrid)、提供使用安全传输入协议SSL的插件(IceSSL)、轻量级的ICE应用防火墙其解决方案(Galcier2)等等,这些留待后面去学习了。


Created by 苑鹏掣

这里写图片描述


原创粉丝点击