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表中。

  与之相反的操作叫做接触激活。这些操作在接口中定义为:

  1. module Ice {  
  2.   
  3.     local interface ObjectAdapter {  
  4.   
  5.         // ...  
  6.   
  7.         //add:把一个具有标志的servant增加到ASM中,返回值是这Servant体现的对象的代理  
  8.   
  9.         Object* add(Object servant,Identity id);    
  10.   
  11.       //addWithUUID:和add相似,不过程序会自动添加Ice对象的标识;可以通过ice_getIdentity来获取该对象代理  
  12.   
  13.         Object* addWithUUID(Object servant);  
  14.   
  15.        //从ASM中解除相应的servant条目  
  16.   
  17.         void remove(Identity id);  
  18.   
  19.         // ...  
  20.   
  21.     };  
  22.   
  23. };   

 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状态。

posted @ 2011-11-21 11:56  tangr206  阅读(765)  评论(0编辑  收藏  举报