1. IceGrid模板
IceGrid模板简化了为应用程序创建描述符的任务。模板是一个参数化的描述符,你可以在任何需要的时候来实例化,而且它们的描述符有各自的权限。模板是IceGrid应用程序的组件,所以它们存储在注册表的数据库中。因此,它们的使用不限于XML文件;也可以使用图形化管理工具交互地创建和实例化模板。
你可以定义服务端和服务描述符的模板。本节的重点是服务端模板;我们会在IceBox集成的上下文中讨论服务描述符的模板。
2. 服务端模版
你可能还记得前面的例子,我们的示例应用程序的XML描述定义了两个几乎相同的服务端:
<icegrid>
<application name="Ripper">
<node name="Node1">
<server id="EncoderServer1" exe="/opt/ripper/bin/server" activation="on-demand">
<adapter name="EncoderAdapter" endpoints="tcp"/>
</server>
</node>
<node name="Node2">
<server id="EncoderServer2" exe="/opt/ripper/bin/server" activation="on-demand">
<adapter name="EncoderAdapter" endpoints="tcp"/>
</server>
</node>
</application>
</icegrid>
这个例子是一个很好的候选服务器模板。下面显示了包含模板的等效定义:
<icegrid>
<application name="Ripper">
<server-template id="EncoderServerTemplate">
<parameter name="index"/>
<server id="EncoderServer${index}" exe="/opt/ripper/bin/server" activation="on-demand">
<adapter name="EncoderAdapter" endpoints="tcp"/>
</server>
</server-template>
<node name="Node1">
<server-instance template="EncoderServerTemplate" index="1"/>
</node>
<node name="Node2">
<server-instance template="EncoderServerTemplate" index="2"/>
</node>
</application>
</icegrid>
我们已经定义了名为EncoderServerTemplate的服务端模板。server-template元素中嵌套的是,定义编码服务器的服务端描述符。这个server元素和我们以前例子之间的唯一区别是,它现在被参数化:模板参数index被用来为服务端和它的适配器形成唯一的标识符。无论它出现在哪里,符号${index}都被替换为索引参数的值。
该模板由server-instance元素实例化,该元素可以在使用了server元素的任何地方使用。服务端实例描述符识别要实例化的模板,并为index提供一个值。
尽管我们没有大幅缩短XML文件的长度,但使它更具可读性。更重要的是,在其他节点上部署此服务端变得更加容易。
3. 模版参数
参数可以使你按需定制每个模版的实例。上面的例子为每个实例定义了不同的index参数,以确保标识符是唯一的。如果没有指定值,参数也可以在模版中声明一个默认值。在我们的示例应用程序中,index参数是必需的,因此不应该有默认值,但是我们可以用另一种方式来说明这个特性。例如,假设服务端的可执行文件的路径名可能会在每个节点上更改。我们可以为该属性提供一个默认值,并在必要时覆盖它:
<icegrid>
<application name="Ripper">
<server-template id="EncoderServerTemplate">
<parameter name="index"/>
<parameter name="exepath" default="/opt/ripper/bin/server"/>
<server id="EncoderServer${index}" exe="${exepath}" activation="on-demand">
<adapter name="EncoderAdapter" endpoints="tcp"/>
</server>
</server-template>
<node name="Node1">
<server-instance template="EncoderServerTemplate" index="1"/>
</node>
<node name="Node2">
<server-instance template="EncoderServerTemplate" index="2"
exepath="/opt/ripper-test/bin/server"/>
</node>
</application>
</icegrid>
如你所见,Node1上的实例使用新参数exepath的默认值,但Node2上的实例,为服务端的可执行文件定义了不同的位置。
理解描述符变量和参数的语义将帮助你为IceGrid应用增加灵活性。
4. 给服务端实例增加属性
正如我们在上一节看到的那样,模板参数允许你自定义服务器模板的每个实例,而具有默认值的模板参数允许你定义常用的配置选项。但是,您可能希望为一个给定的实例一个额外的配置属性,而无需添加参数。例如,要调试特定节点上的服务器实例,可能需要使用Ice.Trace.Network属性集启动服务器;不得不添加一个参数到模板来设置该属性。
为了迎合这种情况,可以在不修改模板的情况下为服务端实例指定其他属性。你可以在server-instance元素中定义这样的属性,例如:
<icegrid>
<application>
...
<node name="Node2">
<server-instance template="EncoderServerTemplate" index="2">
<properties>
<property name="Ice.Trace.Network" value="2"/>
</properties>
</server-instance>
</node>
</application>
</icegrid>
这为特定的服务器设置Ice.Trace.Network属性。
5. 默认模版
IceGrid注册表可以为你的应用程序,配置使用任意数量的默认模版描述符。配置属性IceGrid.Registry.DefaultTemplates指定包含模板定义了XML文件的路径。这样的模板文件在Ice发行版中命名为config/templates.xml,它包含部署Ice服务的实用模板,例如:IcePatch2和Glacier2。
模板文件必须使用下面展示的结构:
<icegrid>
<application name="DefaultTemplates">
<server-template id="EncoderServerTemplate">
...
</server-template>
</application>
</icegrid>
你给应用程序的名称并不重要,你只能在其中定义服务端和服务模板。在配置注册表使用此文件后,你的默认模板将变为每个导入它们的应用程序可用。
每个应用程序的描述符指明是否应该导入默认模板。(默认情况下,它们不会被导入)如果模板被导入,它们基本上被复制到应用程序描述符中,并且与应用程序本身定义的模板没有区别。因此,对包含默认模板的文件所做的更改,不会影响现有应用程序的描述符。在XML中,属性import-default-templates决定是否导入默认模板,如以下示例所示:
<icegrid>
<application name="Ripper" import-default-templates="true">
...
</application>
</icegrid>
6. 通过icegridadmin使用模版
IceGrid管理工具允许你检查模板,并动态实例化新服务端。首先,让我们让icegridadmin来描述我们之前创建的服务端模板:
$ icegridadmin --Ice.Config=/opt/ripper/config
>>> server template describe Ripper EncoderServerTemplate
该命令生成以下输出:
server template `EncoderServerTemplate'
{
parameters = `index exepath'
server `EncoderServer${index}'
{
exe = `${exepath}'
activation = `on-demand'
properties
{
EncoderAdapter.Endpoints = `tcp'
}
adapter `EncoderAdapter'
{
id = `EncoderAdapter${index}'
replica group id =
endpoints = `tcp'
register process = `false'
server lifetime = `true'
}
}
}
注意,服务端ID是一个参数化的值;只有使用其参数值,对模板进行实例化之后才能对它进行设值。
接下来,我们可以使用icegridadmin在新节点上创建一个编码器服务端模板:
>>> server template instantiate Ripper Node3 EncoderServerTemplate index=3
该命令要求我们确定应用程序、节点和模板,并提供模板所需的任何参数。新的服务端实例永久添加到注册表的数据库中,但是,如果我们打算保留此配置;那么,更新应用程序的XML描述是一个好主意,以反映这些更改并避免潜在的同步问题。