找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 7418|回复: 4

ICE开发初级研究(三)

[复制链接]
发表于 2010-9-14 19:34:40 | 显示全部楼层 |阅读模式
本帖最后由 freeeyes 于 2010-9-15 11:06 编辑

在ICE的Slice里面,还有两个关键词需要补充说明一下。
nonmutating和Idempotent关键字。nonmutating关键字,指的是指定接口操作不会被修改,说白了就是C++的const关键字。Idempotent关键字是指某个操作无论之行多少次,返回结果都是一样的。这个关键字标记的这个对象可以多次反复调用执行,在多线程下也是安全的。
  1. interface UserItems extends Items {
  2.        nonmutating int GetUserItemCount();  //得到用户的Items的个数
  3.        Idempotent  bool use();    //使用Items
  4. };
复制代码
其实上面这个声明,nonmutating在C++里面翻译过来就是const,你完全可以这么替换的看代码,这样比较清晰。至于Idempotent关键字,我个人认为声明的标记意义比较大,至于实用我还没有找到更多的含义。
其实,这两个关键字,在多语言环境下还是多少有点问题的,比如,在python中,nonmutating就会报错,因为python里面没有const这个概念。所以,实用它,见仁见智,如果大家都用C++去写,那么不妨实用它,否则,可以忽略之。
在slice的语法上,有两种设计思路,一种是把Slice里面的对象全部类化,比如:
  1. interface Item{
  2. nonmutating string Itemname();
  3. nonmutating string Itemnamedesc();
  4. nonmutating string Itemicon();
  5. nonmutating int Itemprice();
  6. };
  7. sequence<Item*> ItemList;
复制代码
你也可以这么设计,把接口完全理解成接口,隐藏内部实现接口,不必要的计算过程,不暴露给ICE
  1. struct Item
  2. {
  3. string strItemname;
  4. string strItemnamedesc;
  5. string strItemicon;
  6. string strItemprice;
  7. };
  8. sequence<Item*> ItemList;
  9. interface Item{
  10. nonmutating ItemList GetItems();
  11. };
复制代码
前一种的设计思路是,完全把对象看成对象,作为一个类去理解,后一种是把数据结构和类接口完全分开,思路是这里的接口仅仅是完成对象传输的意义,至于如何取舍,这里要看不同的需求而定。
前两篇文章主要说的是slice语法,下面,我讲一些更有意思的东西。ICE给我们提供了大量的上层服务,更大的简化我们的代码开发量。
IceGrid
这个东西,其实说白了,就是一种网格对象管理器的概念,通过它,你可以方便的把你的对象分布部署到不同的远端,并且通过Grid实现网格的调用。你的客户端只需要访问Grid的节点,至于这个Grid节点后面的对象管理,客户端完全不必知道,Grid会提供算法给你所要的对象,并返回执行结果。
其实,Grid的强大在于它的对象管理,你可以通过ICE的一个工具,清晰的看到所有对象被调用的情况,以及使用日志,崩溃日志和资源使用情况。你可以不必启动你的对象,当有人调用你提供的对象,Grid会自动启动你的对象,这样最大限度的减少了内存占用的情况,不用的对象永远不会启动,只有用到的时候才会启动。
相对而言,配合ICE的Freeze工具,你可以实现一套非常强大的内存对象管理体系,至于Freeze,我会放在下一章去讲,这里先提一句它的特性,Freeze是一个对象管理器,你可以不断的把很多的对象放在里面,它会根据你的对象调用频率,把最频繁访问的对象放在内存里,不常用的对象序列化到硬盘上,并且绑定它自己的数据库进行对象使用频度管理。这个东西是不是很酷?对于大量比如登陆对象请求,你完全可以不用理会大量的用户申请,使用Freeze设计好管理规则,因为它会帮助你把你的内存降到合理的范围,不常用的对象不会占据你的内存,更强的是,你几乎不用写什么代码。还有ICEStorm组件,分布式的消息通知机制,这些东西配合起来,可以完成很多看似很复杂的程序。这里,先详细说说Grid的特性。
呵呵,话题说回来,继续说我的Grid。
在你的ICE路径下,bin下面有一个IceGridGUI.jar程序。
你要运行它,必须先下载一个Java的运行环境,然后启动它,你会看到一个非常不错的管理界面,对,就是它。
这是一个Java写的GUI监控工具,你可以连接到Grid服务器,并显示这个Grid下的所有node的状态。
好,第一步,我们怎么建立一个Grid?
首先,你先建立一个目录,比如,这个目录叫做GridServerCell
在里面,我要建立两个文件和一个目录。
ServerRun.bat
GridServer.config
再建立一个当前文件夹下建立一个目录。
GridData
好了,让我们开始Grid之旅,我相信,它会对你的程序非常有用。
先来看看,我的GridServer.config写了一些什么。
  1. IceGrid.InstanceName=TestIceGrid
  2. #
  3. # The IceGrid locator proxy.
  4. #
  5. Ice.Default.Locator=TestIceGrid/Locator:default -h XXX.XXX.XXX.XXX -p 20000
  6. #
  7. # IceGrid registry configuration.
  8. #
  9. IceGrid.Registry.Client.Endpoints=default -p 20000
  10. IceGrid.Registry.Server.Endpoints=default
  11. IceGrid.Registry.Internal.Endpoints=default
  12. IceGrid.Registry.Data=GridData
  13. IceGrid.Registry.PermissionsVerifier=TestIceGrid/NullPermissionsVerifier
  14. IceGrid.Registry.AdminPermissionsVerifier=TestIceGrid/NullPermissionsVerifier
  15. IceGrid.Registry.SSLPermissionsVerifier=TestIceGrid/NullSSLPermissionsVerifier
  16. IceGrid.Registry.AdminSSLPermissionsVerifier=TestIceGrid/NullSSLPermissionsVerifier
  17. # Trace properties.
  18. #
  19. IceGrid.Node.Trace.Activator=1
  20. #
  21. # Dummy username and password for icegridadmin.
  22. #
  23. IceGridAdmin.Username=freeeyes
  24. IceGridAdmin.Password=freeeyes
复制代码
看着有点晕是吧,实话说,我第一次调试Grid的时候也头大,这么多的东西代表什么含义?不过进过分析,其实并不复杂。很多地方都是固定的。有些地方,需要我们手动写一下。
IceGrid.InstanceName=TestIceGrid
这句话顾名思义,给你的Grid设置一个名称,目前3.4.1这个名字对中文支持不是很好,我们还是使用英文吧,当有人链接你的这个grid节点,这里会返回你的节点名称。
Ice.Default.Locator=TestIceGrid/Locator:default -h XXX.XXX.XXX.XXX -p 20000
这里是设置你的Grid服务器的地址和端口,-h 后面跟着你的IP,-p后面是你的端口。这里要注意,-h 千万别写127.0.0.1这样的地址,因为这个IP是被外面访问的,所以这里必须是别的计算机能找到你的。TestIceGrid是你的服务器名称,以后这个东西不在重复描述。
IceGrid.Registry.Client.Endpoints=default -p 20000
这里指定的是客户端访问的地址和端口。
IceGrid.Registry.Data=GridData
这里GridData指的就是你刚才建立的目录,两个文件和一个目录名,还记得么?当然,你可以使用绝对路径,放在和配置文件不同的地方。因为Grid服务启动后,会记录一些信息和日志,这些东西会自动的写到这些目录下。当然,你必须保证你的这个目录是可以被访问到的,而且是可以写入的。至于ICE写了什么,我在以后给大家补全,这里到目前为止我也只看懂了一部分。
IceGrid.Node.Trace.Activator=1
这里指的是你的Grid节点node可以被激活的个数。
IceGridAdmin.Username=freeeyes
IceGridAdmin.Password=freeeyes
这里指定的是你Grid管理员的用户和密码,意思就是,别人要对你的Grid对象进行控制(在Grid运行过程中),必须要使用密码才能进行。
其他部分,你完全可以理解成固定的,如果要刨根问底,请看ICE的手册,这里不再这里写了。
在看看ServerRun.bat
  1. icegridregistry --Ice.Config=GridServer.config
复制代码
这是一个bat文件(windows下,linux下,你可以做一个sh脚本,一样的,鉴于大家windows系统较多,如果想实现,可以在自己的机器上做实验),--Ice.Config=GridServer.config 这里指定的就是你刚才写的GridServer.config文件。
行了,你的一个Grid服务器建立好了。看吧,不难的。
接下来,我来说说在一个Grid下如何建立节点。这里要理清一个概念,这里的节点,并不是一定要依赖你的对象的,节点可以是空的。当然,这样是没有意义的。你把你的ICE对象适配器注册到这个节点,就可以接受Grid的管理了。节点你可以分步在不同的机器上。
大家听到这里肯定要问,写了这么多,Grid到底是干啥的?
呵呵,对,当初研究到node,我才理解到Grid的强大,比如,举个例子,你有200个对象,分步在20台服务器上,假设,这200个对象都是相同的,那么,我怎么实现,客户端调用对象的时候,完全的分布式呢?当然,你非要说,我把这200个对象地址配置在客户端对象上,我也无话可说。不过,如果对于我客户端,我想达到,我给你一个地址,你只要访问这里,至于这200个对象在什么地方不是你客户端关心的事情,当我使用的时候,这个地址会自动根据负载状态给我分配一个空闲的服务器对象,怎么做?呵呵,如果你想到了这些,说明你已经陈述出Grid的作用了。对,Grid就是干这个使的。对于真正分布式的计算,你可以创立很多的Grid服务器,每个Grid服务器负责处理一类对象,那么这样做,将大大减低你的开发量。同时,Grid增加减少节点,对于客户端来说,可以完全不知道。多方便!这才是我想要的分布式服务!对于客户端,它只需要知道一系列的Grid地址,至于这个Grid后面的网格布局,不是客户端所关心的事情。这才是更棒的网格。
好了,说到这里,我想你已经开始兴奋了吧。
那么让我们看看,如何建立一个Grid服务器对象节点,当然,这个节点的代码是可复制的,并且可以大量的方便复制。
让我们建立一个节点的文件夹,当然,你可以不放在GridServer的机器上,你完全可以找一个别的机器,比如,你同事的机器。
在这个目录里面,你需要建立两个文件和一个文件夹。(这里是不是有点熟悉,对了,和上面的方法是一样的)
node.config
run.bat
还有一个目录
Node(当前文件夹,当然,你也可以放在别处,无所谓的)
让我们看看node.config在干些什么?
  1. #
  2. # The IceGrid locator proxy.
  3. #
  4. Ice.Default.Locator=TestIceGrid/Locator:default -h XXX.XXX.XXX.XXX -p 20000
  5. #
  6. # IceGrid node configuration.
  7. #
  8. IceGrid.Node.Name=node_test
  9. IceGrid.Node.Endpoints=default
  10. IceGrid.Node.Data=Node
  11. #
  12. # Trace properties.
  13. #
  14. IceGrid.Node.Trace.Activator=1
复制代码
Ice.Default.Locator=TestIceGrid/Locator:default -h XXX.XXX.XXX.XXX -p 20000
这行代码指的是你Grid服务器地址,你这个节点会注册到这个Grid管理器中去。
IceGrid.Node.Name=node_test
IceGrid.Node.Endpoints=default
IceGrid.Node.Data=Node
第一个节点名称,第二个是当前节点的地址(一般默认是default),最后一个是制定Node的目录路径(就是刚才建立的Node文件夹)。
好了,一个节点建立完成了。
那么你会问,如何把我的对象适配器绑定给这个node呢?答案是一个xml文件。
你建立一个GridNode.xml
  1. <icegrid>
  2.   <application name="Test">
  3.     <node name="node_Test">
  4.       <server id="TestServer" exe="python" activation="on-demand">
  5.        <option>mynode.py</option>
  6. <adapter name="UserAdapter" endpoints="tcp" register-process="true">
  7.    <object identity="Test" type="::Test::TestICE" property="Identity"/>
  8. </adapter>
  9.       </server>
  10.     </node>
  11.   </application>
  12. </icegrid>
复制代码
这就是这个节点的配置文件<node name="node_Test">

这里的node_Test必须是是你的IceGrid.Node.Name=node_test里面指定的名称。
      <server id="TestServer" exe="python" activation="on-demand">
       <option>mynode.py</option>
这的exe="python" 指的是你的运行文件是一个python文件(这里你可以改成C++)
<option>mynode.py</option>
这个mynode.py就是你的类,如果是C++,你这里应该是mynode.exe。
<object identity="Test" type="::Test::TestICE" property="Identity"/>
这里identity="Test"是客户端要访问你的这个对象的代理名称,type="::Test::TestICE"指的是你的slice文件对应的<模块名>::<接口类>(具体请参见《ICE初级研究一》里面的ice文件)
好了,配置到这里,大功告成。
这个XML,是你的节点配置文件,每个节点通过这个xml来决定,通过<node name="node_Test">来关联你的节点配置文件。告诉节点你要在这个节点上绑定怎样的对象。
最后,当所有的Node启动以后,你需要在IceGridGUI读取这个xml,将你的这个xml合并到你的Node里面。这样做,Grid就能找到你的节点对应的对象位置了。Grid第一次启动,你的对象并不会被启动,只有当有请求到达的时候,Grid会通过这个配置文件找到你的对象,并启动起来,最大的节省你服务运行时的内存。
运行一下你的ServerRun.bat
再运行一下你的节点run.bat
最后运行你的IceGridGUI.jar

点击OK,如果显示出来了你的节点,那么祝贺你,你的Grid写成功了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?用户注册

×
发表于 2010-9-17 16:51:00 | 显示全部楼层
文章不错, 关注中, 请继续写下去。
发表于 2010-10-9 13:46:37 | 显示全部楼层
继续,期待下文
发表于 2010-10-27 16:21:11 | 显示全部楼层
下文 ... 下文 ...
 楼主| 发表于 2010-10-28 18:29:28 | 显示全部楼层
最近忙着填充框架,等有时间我继续写。
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-22 03:06 , Processed in 0.016526 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表