Ice笔记---Ice run time详述
http://blog.csdn.net/moxiaomomo/article/details/6764180
1.Ice Run Time 概述
按照个人暂时的理解,Icerun Time具体是指Ice封装好了大部分的API,通过这些API实现分布式应用程序运行时的各种功能。
首先,其中一个重要的部分是通信器,它是Ice run time的主句柄,也是Ice run time的主进入点。另外Ice一个重要的机制是servant定位器,用于控制性能和内存消耗之间的平衡。其他一些同样不可缺少的组成部分接下来将会进行介绍。
2.通信器
Icerun time 的主进入点由本地接口Ice::Communicator 表示。Ice::Communicator 的一个实例与一些运行时资源是关联在一起的:
1) 客户端线程池:确保客户端至少有一个线程可用于接受对未完成请求的答复处理。同时它可用于异步方法调用(AMI)。
2) 服务端线程池:负责接收到来的连接,并处理来自客户的请求。可用于异步分派(AMD)。
3) 配置属性:配置Icerun time的各方面属性。每个通信器有各自的属性集。
4) 对象工厂:实例化从已知基类继承而来的servant类。
5) 一个日志记录器对象:确定日志消息的处理方式。实现了Ice::Logger接口。
6) 一个统计对象:打印一些通信流量消息等。实现了Ice::Stats接口。
7) 一个缺省路由器:实现了Ice::Router接口。Glacier使用它实现了Ice的防火墙功能。
8) 一个缺省定位器:用于把对象标识解析为代理的对象。IcePack用于构建定位服务。
9) 一个插件管理器:用于给通信器增加特性的对象。ICESSL被实现为插件。
10) 对象适配器:负责分配到来的请求,并把请求分配给相应的servant处理。下一小节将会具体介绍。
通信器提供了一些操作:
1) proxyToString , stringToProxy:这两个操作将代串化,或者相反。
2) createObjectAdapter ,createObjectAdapterWithEndpoints:创建新的对象适配器。
3) shutdown:关闭服务端的Icerun time
4) waitForShutdown:挂起发出调用的线程,直到通信器关闭为止。
5) destroy:销毁通信器及相关资源,例如线程,通信端点以及内存资源。
3.对象适配器
3.1概述
一个通信器含有一个或者多个对象适配器。对象适配器处在Ice run time和服务器之间的界线上,负责;
1) 把ice对象映射到到来请求的servant,并把请求分配给相应servant对象来处理。
2) 协助进行生命周期操作,避免出现Ice对象和servan的建立与销毁时出现冲突。
3) 提供一个或者多个传输端点。每个适配器有一个或多个servant。
3.2 活动Servant映射表
每个对象适配器都维护有一个叫做活动servant映射表(ASM: Active Servant Map)。活动表的作用可以用一下这图表示:
因此它的功能可以描述为:把请求绑定到相应的正确的servant。图中示例用了直接代理,它将传输端点嵌在了代理中。
3.3)Servant激活与解除激活
激活的意思是指:向Ice run time告知某个ice对象的servant的存在。具体操作就是将servant对象指针添加到ASM表中。
与之相反的操作叫做接触激活。这些操作在接口中定义为:
- module Ice {
- local interface ObjectAdapter {
- // ...
- //add:把一个具有标志的servant增加到ASM中,返回值是这Servant体现的对象的代理
- Object* add(Object servant,Identity id);
- //addWithUUID:和add相似,不过程序会自动添加Ice对象的标识;可以通过ice_getIdentity来获取该对象代理
- Object* addWithUUID(Object servant);
- //从ASM中解除相应的servant条目
- void remove(Identity id);
- // ...
- };
- };
3.)适配器的状态:
a)activate:活动状态,适配器可以进行连接过来的请求的分派工作。
b)hold:扣留状态,此时到达过来的请求会被扣留,不会被分派到相应的servant处理。
发出调用的线程会立即返回,不会等待操作完成。
c)waitForHold:挂起发出调用的线程,直到适配器状态移到扣留状态。
d)Deactivate:之后到达的请求会被拒绝,但正在执行的请求可以完成。
e)WaitForDeactivate:挂起发出调用的线程,直到适配器迁移到Deactivate状态为止。
Servant定位器
之前 介 绍了ASM表(servant活动映射表)的作用。不过他也会有一些限制,因为如果是使用适配器的ASM来把Ice对象映射到servents,那么会有 一些影响:(1)每个Ice对象都有一个不同的servant代表。(2)所有Ice对象的所有servants都永久性的出在内存中。如果有大量的上 servant对象的话,那么服务器将会承受大的压力,或许是内存不够,或许是初始化所有servants的时间很长。
1. locator综述
Servant定位器是一种本地对象,我们负责实现它,并把它息道对象适配器上。适配器一旦有了servant定位器,它可以和平常一样查询 ASM,对servant进行定位。如果ASM上能找到相对应的servant,请求就会分派给这个servant。如果找不到的话,对象适配器就会回调 servant定位器,它为该请求提供servant。Servant定位器会做一下事情中的一件:
--初始化一个servant,把它传给Ice run time,这种情况下,请求会被分派到这个新实例化的servant。
--servant定位器告诉Ice run time,他没有找到相应的servant。这种情况下,客户会受到ObjectNotExistException的异常。
采用这种简单的机制,我们的服务器能让我们访问数量不限的Ice对象:服务器不必为每一个现有的Ice对象实例化一个单独的servant。提供数 据库访问的服务器常常使用servant定位器:数据库中的条目数通常远远大于服务器在内存中能够存储的条目数。用于进程控制或网络管理的服务器也常常会 使用servant定位器。
2. Servant定位器接口
module Ice {
local interface ServantLocator {
Object locate( Current curr,out LocalObject cookie);
void finished( Current curr,Object servant,LocalObject cookie);
void deactivate();
};
};
ServantLocator是一个本地接口。为了创建实际的servant定位器实现,我们必须定义一个从Ice::ServantLocator派生的类,并实现locate,finised以及deactivate操作。
locate:只要有请求到达,而且他在ASM中没有对应的条目,Ice run time就会调用locate。
finished:一旦请求完成,Ice run time就会调用finished,把完成了操作的servant、该请求的Current对象以及locate在一开始创建的cookie传给它。这意味着,每一个locate都会有一个对应的finished。
Deactivate:当servant定位器所属的对象适配器接解除激活时,Ice run time会调用deactivate操作。
3. 针对Servant定位器的线程保证
在必要时,我们必须使用互斥原语,在locate和finished中对共享数据进行保护。
4. Servant定位器的注册
对象适配器不会自动的了解到一个servant定位器,我们要显式地向对象适配器注册servant定位器。
module Ice {
local interface ObjectAdapter {
// ...
void addServantLocator(ServantLocator locator,
string category);
ServantLocator findServantLocator(string category);
// ...
};
};
由上可以看出对象适配器允许我们增加和查找servant定位器。以下是servant定位器的简单功能流程示意图:
5. 使用cookies
有时,我们需要在locate与finished之间传递信息。例如,locate的实现可以根据负载或可用性,从多种数据库后端选取一种;同时, 为了适当执行结束工作,finished的实现可能需要知道locate使用的是哪一种数据库;在操作调用完成之后,Ice run time会把这个cookie的值传给finished。
Cookie必须从Ice::LocalObject派生,可以容纳任何对我们的实现有用的状态和成员函数
服务器实现技术
1. 渐进的初始化
如果我们使用servant定位器,locate返回的servant只能用于当前请求,也就是说Ice run time不会把这个servant增加到Active Servant Map中。
一种常用的实现技术是,在locate中,把每个servant增加到ASM中。这意味着,只有对Ice对象的初次请求会触发对locate的调用;自此之后,与Ice对象对应的servant就可以在ASM中找到,Ice run time不必再调用servant定位器就可以立即分派针对同一个Ice对象的到来请求。
使用一个把servant增加到ASM中的定位器有一些优点:
1) Servants是随需实例化的,所以servant的初始化代价分散到了许多次调用中,而不是在服务器启动时同时产生。
2) 服务器的内存需求降低了,因为只有当Ice对象被客户实际访问时,servant才会实例化。
2. 缺省Servants
缺省Servants是—它针对每一个请求,充当不同的Ice对象的角色。换句话说,缺省servant会在处理每个请求时,根据请求所访问的对象标识改变其行为。通过这样的方式,客户可以访问数量不限的Ice对象,但却只有一个servant在内存中。
缺省Servants不仅可以节省内存,实现方式也很简单:在本质上,它们就是数据库中对象的持久状态的façade。
要创建缺省servant实现,我们需要的定位器的数量和系统中的非抽象接口的数量一样多。而对于每一个被调用的操作,缺省servant都要进行一次数据库访问,因此它比在内存中缓存状态要慢。
3. 混合途径及缓存
如果我们的应用有一些经常访问的对象,是性能的关键,那么我们可以把针对这些对象的servant增加到ASM中。其他不常被访问的对象可以通过缺省servant实现。
4. Servant逐出器
逐出器是维护有servants缓存的servant定位器:最近最少用的servant处在队列的尾部,最近使用最多的servant处在队列的头部。(按照LRU顺序维护)。
队列的长度可以配置,并决定会有多少servant存放在缓存中:如果针对某个Ice对象的请求在内存中没有对应的servant,而且缓存满了,逐出器就会在队尾移除最近最少用的servant,给要在对头实例化的servant腾出空间。如:
逐出器在访问了servant3之后的情况:
假定下一个客户请求时针对对象标识6的。逐出器中维护servants的缓存已经满了,那么就会在队尾逐出标志位1的servant,如图:
逐出器集合了ASM与缺省Servants的优点:只要缓存尺寸能在内存中容纳servant工作集,大多数的请求都会由已经实例化的servant提供服务,而不用创建servant,并访问数据库来初始化servant状态。