绝大多数的分布式系统都有一个共同特点,分布在各个主机上的节点进程并不是完全独立的,彼此之间有相互联系和通信,集群对集群中的节点有一些控制指令,如部署,停止,或者调整参数等。IceGrid为了达到这一目标,设计了IceGrid Node。
负责IceBox的装载和启停
采集主机的负载信息
执行控制器IceGrid Admin的指令
IceGrid Node类似于一个容器,启动以后,会安装预先定义的配置文件,加载其中的IceBox,并根据要求启动或停止其中的一个或多个IceBox进程。
一个IceGrid中可以部署多个IceBox实例,这些实例可以是同一个IceBox的多个实例进程,也可以是完全不同的IceBox实例的组合,IceGrid Node连同其上运行的IceBox实例的信息同步到了registry中。
(1)node配置文件node1.cfg
#指定主注册节点的位置
Ice.Default.Locator=IceGrid/Locator:tcp -h 127.0.0.1 -p 7061
#设置节点1相关数据的存储目录
IceGrid.Node.Data=D:\data1\node
#指定节点1用于监听客户端连接的端口号
IceGrid.Node.Endpoints=tcp -p 5061
#指定节点1的名称
IceGrid.Node.Name=node1
Ice.StdErr=D:\data1\node\node.stdout.log
#指定错误日志文件
Ice.StdOut=D:\data1\node\node.stderr.log
(2) 启动IceGrid管理工具
icegridadmin -u test -p test --Ice.Default.Locator="IceGrid/Locator:tcp -h 127.0.0.1 -p 7061"
(3) Icegrid Application
对一个分布式系统来说,拓扑是一个很重要的概念,什么服务部署在哪些容器中,这些容器又分布在哪些机器上,J2EE没有解决这个问题,如果发布一个WAR到几个Tomcat容器中,必须一个一个执行部署,而这个部署还涉及容器的启停,为了解决这个问题,Ice提出了IceGrid Application的概念,并给出了一个XML文件来定义Application,在定义好这个Application之后,可以通过icegridadmin 来完成自动分布式部署过程了,升级也同样轻松。
最主要的就是application.xml
<?xml version="1.0" encoding="utf-8"?>
<icegrid>
<application name="BookIceApp"> <!-- 必须设置应用的名称 -->
<properties id="MultiThreaded">
<property name="Ice.ThreadPool.Server.Size" value="50"/>
<property name="Ice.ThreadPool.Server.SizeWarn" value="150"/>
<property name="Ice.ThreadPool.Server.SizeMax" value="200"/>
<property name="IceBox.InheritProperties" value="1"/>
<property name="Ice.Override.ConnectTimeout" value="5000" />
<property name="Ice.Override.Timeout" value="10000" />
<property name="Ice.Default.LocatorCacheTimeout" value="300" />
<property name="Ice.BackgroundLocatorCacheUpdates" value="1" />
</properties>
<server-template id="BookIceTemplate">
<parameter name="index" />
<icebox id="icebox-${index}" exe="java" activation="on-demand">
<properties>
<properties refid="MultiThreaded"></properties>
</properties>
<option>-Xms2G</option>
<option>-Xmx2G</option>
<option>IceBox.Server</option>
<env>CLASSPATH=D:\software\ZeroC\Ice-3.5.1\lib\*;D:\software\eclipsemars\ice\BookIce\lib\*;D:\software\eclipsemars\ice\BookIce\bin</env>
<service name="OnlineBookService" entry="com.bookice.OnlineBookImpl">
<adapter name="OnlineBookService" id="OnlineBookService-${index}" endpoints="tcp"
replica-group="OnlineBookRep"/>
</service>
<service name="SMSService" entry="com.smsice.SMSserviceImpl">
<adapter name="SMSService" id="SMSService-${index}" endpoints="tcp"
replica-group="SMSRep"/>
</service>
</icebox>
</server-template>
<replica-group id="OnlineBookRep">
<load-balancing type="adaptive" n-replicas="0"/>
<object identity="OnlineBookService" type="::book::OnlineBook"/>
</replica-group>
<replica-group id="SMSRep">
<load-balancing type="round-robin" n-replicas="0"/>
<object identity="SMSService" type=":::message::SMSService"/>
</replica-group>
<node name="node1">
<server-instance template="BookIceTemplate" index="1"/>
<server-instance template="BookIceTemplate" index="2"/>
</node>
</application>
</icegrid>
注意点:
(1)server-template中的env配置,注意自己的类以文件结尾,不要加\* 之类的。
(4) 再修改Client访问用的id
修改:
ce.ObjectPrx base = ic.stringToProxy("OnlineBookService");
更加简洁,如果约定一个命名规则,则可以不进行交流,分别完成开发客户端应用。
(5) 运行图片
前面的均不变,主要是增加了一个app.xml配置文件,并修改了client中的一句 stringToProxy