ICE中间件说明文档
1 ICE中间件简介
Ice 是 Internet CommunicationsEngine 的简称,是一种面向对象的中间件平台,支持面向对象的RPC编程,其最初的目的是为了提供类似CORBA技术的强大功能,又能消除CORBA技术的复杂性。该平台为构建面向对象的客户-服务器应用提供了工具、API 和库支持。
ICE平台还提供一序列的编程库,包括线程模型库、定时器、信号处理器,这些编程库的API全部支持线程安全。
ICE目前的最新版本为ICE3.4.1,是2010年6月份发布的,ICE3.1.1(2006年10月份发布)及以前的版本支持Windows、LINUX、AIX、HP-UX、Solaris操作系统,但是ICE3.2.0(包含)以后的版本官方不再保证对AIX的完全支持,而3.3.1(包含)以后版本连HP-UX都不保证完全支持,虽然源代码中仍然提供了这两个操作系统下的源代码编译文件Make.rules.AIX和 Make.rules.HP-UX,根据官方的论坛说明是因为他们基本上没有这两个系统的商业客户,所以不再对这两个平台进行代码测试,如果有需要的需要和他们联系。
2 平台核心功能
2.1 接口描述语言(Slice)
Slice (Specification Language forIce)是一种用于使对象接口与其实现相分离的基础性抽象机制。Slice 在客户与服务器之间建立合约,描述应用所使用的各种类型及对象接口。这种描述与实现语言无关,所以编写客户所用的语言是否与编写服务器所用的语言相同,这没有什么关系。
Slice 定义由编译器编译到特定的实现语言。编译器把与语言无关的定义翻译成针对特定语言的类型定义和API。开发者使用这些类型和API 来提供应用功能,并与Ice 交互。目前ICE支持Slice到C++、JAVA、C#、Python、Ruby、PHP的语言映射。
Slice示例:
module Family //对应C++的名字空间
{
interface Child;
sequence<Child*> Children; //OK 可以利用C++的Vector
interface Parent//对应C++的类
{
Children getChildren(); //OK
};
interface Child
{
Parent* getMother();
Parent* getFather();
};
};
利用Slice 定义接口/类方法时和其他编程语言很相似,需要一个返回值和若干个参数,但是需要注意的是Slice不支持引用方式的参数传递,参数要么为输入参数,要么为输出参数,不同时为in和out.作为out参数的时候,不管客户端对out参数的初始赋值是什么,在服务端都取不到该,但是服务端可以对该参数进行赋值,再传递给客户端。例如:
interface Hello
{
};
2.2 ICE运行时
2.2.1 通信器
Ice run time 的主进入点由本地接口Ice::Communicator 表示,通常一个应用服务器只使用一个通信器,一个通信器实例管理着运行时资源,主要的运行时资源包括:
²
²
²
²
²
²
2.2.2 对象适配器
一个通信器含有一个或更多对象适配器。对象适配器处在Ice run time和服务器之间的界线上,负有这样一些责任:
²
²
²
²
2.2.3 位置透明性
Ice run time 的一个有用的特性是位置透明性:客户无需知道Ice 对象的实现的位置;对某个对象的调用会被自动引导到正确的目标,不管这个对象的实现是在本地地址空间中,在同一台机器上的另一个地址空间中,还是在一台远地机器上的另一个地址空间中。位置透明性十分重要,因为有了它,我们能够改变对象实现的位置,而不会破坏客户程序,同时,通过使用IceGrid,像域名和端口号这样的信息可以放在应用的外部,不用出现在串化代理中。
2.3 异步编程模型
ICE平台支持客户端异步调用(AMI)和服务端异步分派编程(AMD)。
2.3.1 异步方法调用
异步方法调用(AMI) 这个术语描述的是客户端的异步编程模型支持。如果你使用AMI 发出远地调用,在Ice run time 等待答复的同时,发出调用的线程不会阻塞。相反,发出调用的线程可以继续进行各种活动,当答复最终到达时,Ice run time 会通知应用。通知是通过回调发给应用提供的编程语言对象的。
要使用异步方法调用,只需要给对应的类或者方法前面加上元数据[“ami”],示例如下:
interface Hello
{
};
通过Slice编译器生成头文件时,会生成对应的方法同步调用方法和异步调用方法,用户在客户端可以自行选择使用同步调用还是异步调用,非常方便。编译后对于每一个异步方法都会生成相应的异步回调类和异步调用代理方法,类的命名方式AMI_类名_方法名,上述的slice经编译后生成的类为 AMI_Hello_sayHello,同时这个类提供了两个方法:
voidice_response(<params>);
表明操作已成功完成。各个参数代表的是操作的返回值及out 参数。如果操作的有一个非void 返回类型, ice_response 方法的第一个参数就是操作的返回值。操作的所有out 参数都按照声明时的次序,跟在返回值的后面。
void ice_exception(constIce::Exception &);
表明抛出了本地或用户异常。
客户端只需要从AMI_Hello_sayHello类继续并实现上述两个方法就可以了。示例代码如下:
class AMI_Hello_sayHelloI : public AMI_Hello_sayHello
{
};
生成的异步调用代理方法命名为方法名_async,上述示例生成的方法为 sayHello_async.然后客户端的程序异步调用如下:
hello->sayHello_async(AMI_Hello_sayHelloPtr,<params>);
然后只需在ice_response方法处理返回结果。
也可以调用同步方法:
hello->sayHello(<params>);
2.3.2 异步方法分派
异步方法分派(AMD) 是AMI 的服务器端等价物,在使用AMD 时,服务器可以接收一个请求,然后挂起其处理,以尽快释放分派线程。当处理恢复、结果已得出时,服务器要使用Ice runtime 提供的回调对象,显式地发送响应。
用实际的术语说, AMD 操作通常会把请求数据(也就是,回调对象和操作参数)放入队列,供应用的某个线程(或线程池)随后处理用。这样,服务器就使分派线程的使用率降到了最低限度,能够高效地支持大量并发客户。
要使用异步方法调用,只需要给对应的类或者方法前面加上元数据[“amd”],示例如下:
interface Hello
{
};
和异步方法调用不同的是,异步分派是服务端的,在服务端会生成相应的异步分派类和异步分派方法。服务端的分派器在接收到客户请求时把请求分派给sayHello_async(constDemo::AMD_Hello_sayHelloPtr&, int, constIce::Current&).然后用户可以在该方法内把任务参数信息放入队列,在队列中循环检查任务并处理,处理完成后调用AMD_Hello_sayHelloPtr类的 ice_response 方法返回给客户端。
2.4 订阅/发布编程模型
IceStorm是一个高效的用于ICE应用的发布/订阅服务,IceStorm有几个比较重要的概念:
²
²
²
²
IceStorm支持两个主要的QOS参数reliability 和 retryCount,reliability的取值分别为ordered 和空值,取ordered时,发布者发布的消息会保证按顺序递送给订阅者。
从IceStorm提供的功能来看,对于不需要进行消息持久存储转发的应用来说很适合,但是由于在订阅者出错后立即解除订阅关系,不是由订阅者主动解除,这个在应用中需要特别注意是否符合实际应用。
IceStorm被实现为IceBox服务,所以在部署IceStorm应用时需要启动IceBox服务。
2.5 动态服务管理(IceBox)
IceBox 用于动态加载用户服务并对他们进行集中管理,可以通过iceboxadmin管理工具对IceBox中的服务进行远程管理,通过IceBox用户服务可以被开发成可以动态加载的动态库组件.
使用IceBox的服务组件需要继承IceBox::Service类,并实现start()、stop()方法,并在实现类中提供服务进入点函数,一般为create()函数,在这函数中创建服务实现类的对象并返回。例如:
extern "C"
{
ICE_DECLSPEC_EXPORTIceBox::Service*
create(Ice::CommunicatorPtrcommunicator)
{
}
}
iceboxadmin [options][command...]
Commands:
start SERVICE Start aservice.
stop SERVICE Stop aservice.
shutdown Shutdown theserver.