ice 服务集群配置说明

本文档详细介绍了ICE服务集群的配置,包括slice语言的基础概念,如接口、异常、类的定义,以及服务端的objectadapter、servant和identity。接着讨论了icebox,一个ICE程序框架,用于统一管理多个服务,并提供了服务解耦和性能优化的优势。然后阐述了icegrid的结构和工作原理,强调了registry和node的角色以及服务的部署流程。最后,通过示例展示了直接连接和间接代理模式的区别以及配置方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、the  slice  language

  1. 基础类型的string 对应于c++里的std::string
  2. module对应与c++的namespace,注意首字母大写
  3. 可以定义常量 const string aa="aaa";
  4. 自定义类型 struct 中只包含基础类型成员.
  5. interface

    • interface主要用于client的调用,所以应该只含有操作,不能定义类型,异常和数据成员。
    • 参数中从client到server是input参数,从server到client是output参数。
      interface CircadianRhythm {
      void setSleepPeriod(TimeOfDay startTime, TimeOfDay stopTime);
      void getSleepPeriod(out TimeOfDay startTime,out TimeOfDay stopTime);
      };
    • 如果同时存在入参和出参,则出参排入参后
      void getSleepPeriod(TimeOfDay startTime,out TimeOfDay stopTime);
      当有多个出参时,可以封装到一个结构中,返回值为void.
    • 不存在既是入参也是出参的参数。
    • interface中的操作不允许重名。
    • nonmutating 表示只读操作,idempotent表示多次执行此操作不会改变server的状态.
      为了更积极的容错,建议加这两个关键字(http://blog.csdn.net/biexf/article/details/6087441)
      
      interface Clock
              {
                      nonmutating TimeOfDay getTime();
                      idempotent void setTime(TimeOfDay time);
              };
    • interface支持继承,多继承
      interface a extends b,c {}; //从b,c中继承的操作不能有重名
      所有interface的公共base interface是 Object。interface与 产生的Prx相关联的,ObjectPrx是所有proxy的基类,
      例:ClockPrx的基类是ObjectPrx,slice2cpp中生成的类的公共基类是::Ice::Object
      
    • proxy中含有指针语义,所以可以定义自引用接口
      interface Link {
          idempotent SomeType getValue();
         idempotent Link* next();
      };
      The Link interface contains a next operation that returns a proxy to a Link interface. Obviously, this can be used to create a chain of interfaces; the final link
      in the chain returns a null proxy from its next operation.

  6. exception
    分为 用户自定义异常 和 运行时异常.
  • 用户自定义异常。 自定义异常支持继承
    exception ErrorBase {
    string reason;
    };
    enum RTError {
    DivideByZero, NegativeRoot, IllegalNull /* ... */
    };
    exception RuntimeError extends ErrorBase {
    RTError err;
    };
    抛出异常
    interface Clock {
        idempotent TimeOfDay getTime();
        idempotent void setTime(TimeOfDay time)  throws RangeError, Error;
    };
  • Ice::Exception 是所有异常类的基类,用户自定义异常的基类Ice::UserException., 运行时异常Ice::LocalException

7.  在服务端一个objectadapter占用一个端口,在每个objectadapter中可以放置多个servant. 每个servant都可独立完成不用的功能. 每个一个servant都有唯一一个identity (一个字符串)作为标识。所以客户端产生一个指定具体功能的proxy 需要提供identity, 协议类型,监听ip和 监听端口,如:SimplePrinter:tcp -h 10.3.18.163 -p 10000。此proxy主要表示server的资源,所以即使在其它机器上通过此proxy调用,结果一致。对proxy的打印 :clock -t:tcp -h 10.3.18.163 -p 10000

8.  client和server在进行数据交互,除了基本数据,用户定义数据类型外,还可以是proxy, 在获取某个servant的proxy后,可以直接进行对该servant的方法的调用,参见test2

9.   class

  • class 允许成员为空,struct不可已。当class中只包含成员变量时,作用与struct相同,但class优点是可以继承。class 只支持单继承,struct不支持。
    class 中可以有操作,struct不可已。class支持自引用.
     建议少用class 除非有必要理由,用class会消耗更多的资源。若在在开发中尽量用struct+interface来搞定问题,除非有足够的里有用class

二、 icebox

  1. 一个ice 程序框架。用一个icebox server同一管理多个icebox服务,有点如下:
    • 被同一IceBox加载的Ice服务可以通过配置来获得Ice性能优化的好处,举个例子:如果一个应用是另外一个Ice服务的Client,同时client和server都在同一个IceBox里被配置,那么客户端和服务端之间的执行可以获得优化;
    • 应用的不同服务(Service)之间的组合是通过IceBox的配置来完成,而不是通过硬编码(Compiling and Linking),这样可以对Server中的服务(Service)进行解耦,允许服务(Service)本身根据需要组合或者分离;
    •  IceBox支持在IceGrid(the server activation and deployment service)中的集成;
    • 应用组件可以用动态链接库的形式发布而不是一个进程的形式发布。这就减轻了系统的负载。例如,你可以在一个JVM中运行若干个应用组件而不是有多个进程,每一个进程都有自己的JVM;
    • IceBox中配置的Ice服务需要继承实现IceBox.Service接口,这样就为开发者提供了一种通用的开发框架和一个集中的管理设备;

  2. 参见icebox的test代码,一个icebox进程是一个icebox server,这个server中可存在多个服务,在一个服务中只包含一个objectadapter, 一个objectadapter中包含多个servant.
    • 一个服务的启动,nohup icebox --IceBox.Service.mmmm=HelloWorld:create --mmmm.Endpoints="tcp -p 10001" > test.log 2>&1 &。其中mmmm作为了objectadapter的名称。 endpoints指定了这个服务adapter的地址。
      IceBox.Service.name=entry_point [args] //name 在一个icebox server中唯一
    • 一个icebox server中启动多个服务, nohup icebox --IceBox.Service.mmmm=HelloWorld:create --mmmm.Endpoints="tcp -p 10001"  --IceBox.Service.nnnn=HelloWorld:create --nnnn.Endpoints="tcp -p 10002" > test.log 2>&    1 &。
      这个对应与上第四点,多个服务存在于一个进程中。
  3. icebox server提供了一些管理功能,详见文档

三、 icegrid

  1. icegrid 结构:一个icegrid结构由 一个registry和一些node组成,通常每一个node在一个主机上,由于registry消耗的资源较少,通常将registry和node放在一起,不过实际证明这是不可取的。每个node都负责启动并监控分配给它的server进程,在server进程中包含具体的多个应用。例如:node上的一个icebox server进程,这个icebox server中可包含多个有具体应用的服务 service。每个服务service中可存在一个object adapter,这个名称必须在registry注册中唯一
    client把服务信息(object和object adapter唯一标识)传给registry, registry将它转换为endpoint返给client,client通过这个endpoint建立连接。client和server在初次连接时通过registry,后续交互时,client通过endpoint直接连接。如果发现无法联通,client就会再次查询registry。
  2. 参见示例 BasicGrid,  这个模式是最简单的间接代理模式,不需要用部署,直接启动server连接registry注册。
    一、启动流程
    1. 启动registry
      icegridregistry --Ice.Config=config/icegridregistry.cfg
    2. 启动server
      src/server/server --Ice.Config=config/server.cfg
    3. 启动client完成调用
      src/client/client --Ice.Config=config/client.cfg
     
    二、配置文件说明
    1.icegridregistry.cfg
      a.  IceGrid.Registry.Client.Endpoints=tcp -p 4061 -h localhost
      最终要的是这个,server和client 通过这个ip和port连接到registry进行相应活动的请求
      b.  IceGrid.Registry.DynamicRegistration=1
      icegrid默认情况下,是不允许objectadapter不经过部署直接注册到registry,如果这个值设成1就可以.
      如果设成0,server直接注册,返回Ice::NotRegisteredException: no object adapter with id `clientadapter' is registered.
    2. server.cfg
      a. Ice.Default.Locator=XNTalk/Locator:tcp -h localhost -p 4061  
      server通过这个配置去连接registry
      b. SimplePrinter.AdapterId=clientadapter
      SimplePrinter是objectadapter的名称,clientadapter是 client访问的adapter,代码Ice::ObjectPrx base = ic->stringToProxy("Hello@clientadapter");
    设置这个项会使objectadapter不在创建直接代理,而是创建一个可用registry解析的间接代理. clientdadapter必须在registry范围内唯一。
      c. SimplePrinter.Endpoints=tcp
      设置objectadapter的监听方式,ip是本机,port由registry分配
    3. client.cfg
      a. Ice.Default.Locator=XNTalk/Locator:tcp -h localhost -p 4061  
      client通过这个配置去连接registry

    三、补充
    在直接连接模式下,client通过servent+tcp/udp+ip+port,完成对server的连接。
    在间接的模式下,通过servent+ objectadapter名 完成调用服务的定位
  3. 参见 AppGrid,带部署功能的icegrid,服务逻辑是可执行程序。

    一、步骤
     1. 配置 descriptor
     2. 启动registry
       icegridregistry --Ice.Config=config/icegridregistry.cfg
     3. 启动node
       icegridnode --Ice.Config=config/icegridnode.cfg
     4. admin 部署服务
       icegridadmin --Ice.Config=icegridadmin.cfg
       a. 执行 application add config/application.xml
     5. 启动client进行访问服务
       src/client/client --Ice.Config=config/client.cfg

    二、说明
     1.  
        <icegrid>
          <application name="XNTalk">
            <node name="node1">
              <server id="SimplePrinterServer" exe="src/server/server" activation="on-demand">
                <adapter name="SimplePrinter" id="clientadapter" endpoints="tcp" />
              </server>
            </node>
          </application>
        </icegrid>
         a. node 名称最好用抽象名,不要用机器名等,在一台主机上可以部署多个node,但在典型的配置中不会这么做。
         b. 在一个node下可以有多个server. icegridadmin下 server list可以展示
         c. 在一个server下可以有多个object adapter,name 是object adapter在server端的创建名称,id是oa在registry的注册名称.
            如果id 属性存在,则在一个registry下注册的 oa的名称必须唯一, client也通过这个名称定位。Ice::ObjectPrx base = ic->stringToProxy("Hello@clientadapter");
            如果id 属性不存在,则client可以通过servant@server_id.adater_name访问,只要server_id.adater_name唯一即可。访问方式
            Ice::ObjectPrx base = ic->stringToProxy("Hello@SimplePrinterServer.SimplePrinter"); 一个叫常用的方式server_id在变化,adapter_name固定。
            只要存在id,这种访问方式就会失败.
     2. icegridregistry
         a. IceGrid.Registry.Client.Endpoints=tcp -p 4061 -h localhost  提供访问监听的端口
         b. IceGrid.Registry.Data=registry   registry的数据库目录,必须在启动前创建
     3. icegridnode
         a. Ice.Default.Locator=XNTalk/Locator:tcp -h localhost -p 4061
         b. IceGrid.Node.Name=node1    名称必须唯一
         c.  IceGrid.Node.Data=node   node的数据库目录
         d. IceGrid.Registry.Server.Endpoints=tcp    这个配置写错了,node 连不上
         e. IceGrid.Registry.Internal.Endpoints=tcp
     4. icegridadmin
        Ice.Default.Locator=XNTalk/Locator:tcp -h localhost -p 4061
     5. client
        a. Ice.Default.Locator=XNTalk/Locator:tcp -h localhost -p 4061
        b. 在同一个服务布多份时,两种descriptor配置方式,adapter的name是不变的,只有server和adapter的id在变,在client端基本采用下列  
           string adapter;
           if ((rand() % 2) == 0)
             adapter = "EncoderServer1.EncoderAdapter";
           else
             adapter = "EncoderServer2.EncoderAdapter";
           Ice::ObjectPrx proxy = communicator->stringToProxy("factory@" + adapter);
  4. 参见IceboxGrid,带部署功能的icegrid,服务逻辑是so。
    一、步骤
     1. 配置 descriptor
     2. 启动registry
       icegridregistry --Ice.Config=config/icegridregistry.cfg
     3. 启动node
       icegridnode --Ice.Config=config/icegridnode.cfg
     4. admin 部署服务
       icegridadmin --Ice.Config=icegridadmin.cfg
       a. 执行 application add config/application.xml
     5. 启动client进行访问服务
       src/client/client --Ice.Config=config/client.cfg
    二、说明
     1.  
         <icegrid>
           <application name="XNTalk">
             <node name="node1">
               <icebox id="IceBoxServer" exe="icebox" activation="on-demand">
                  <env>LD_LIBRARY_PATH=src/server:$LD_LIBRARY_PATH</env>
                  <service name="HelloService" entry="HelloService:create">
                     <adapter id="dingding" name="${service}" endpoints="tcp"/>
                  </service>
               </icebox>
             </node>
           </application>
         </icegrid>
         a. node 名称最好用抽象名,不要用机器名等,在一台主机上可以部署多个node,但在典型的配置中不会这么做。
         b. 在一个node下可以有多个icebox server. icegridadmin下 server list可以展示
         c. 在一个icebox下可以有多个service。每个service对应一个so文件,每个service中可以存在多个object adapter。
            name 是object adapter在server端的创建名称,id是oa在registry的注册名称.在一个registry下注册的 oa的名称必须唯一, client也通过这个名称定位。
            Ice::ObjectPrx base = ic->stringToProxy("Hello@dingding");
            如果id 属性不存在,在object adapter在registry中的注册名称icebox_id+service_name+adapter_name. client的方式方式
            Ice::ObjectPrx base = ic->stringToProxy("Hello@IceBoxServer.HelloService.HelloService");
     2. icegridregistry
         a. IceGrid.Registry.Client.Endpoints=tcp -p 4061 -h localhost  提供访问监听的端口
         b. IceGrid.Registry.Data=registry   registry的数据库目录,必须在启动前创建
     3. icegridnode
         a. Ice.Default.Locator=XNTalk/Locator:tcp -h localhost -p 4061
         b. IceGrid.Node.Name=node1    名称必须唯一
         c.  IceGrid.Node.Data=node   node的数据库目录
     4. icegridadmin
        Ice.Default.Locator=XNTalk/Locator:tcp -h localhost -p 4061
     5. client
        a. Ice.Default.Locator=XNTalk/Locator:tcp -h localhost -p 4061
        b. 在同一个服务布多份时,两种descriptor配置方式,adapter的name是不变的,只有server和adapter的id在变,在client端基本采用下列
           string adapter;
           if ((rand() % 2) == 0)
             adapter = "EncoderServer1.EncoderAdapter";
           else
             adapter = "EncoderServer2.EncoderAdapter";
           Ice::ObjectPrx proxy = communicator->stringToProxy("factory@" + adapter);
    三、补充
    1. client在间接代理通过object+ object adapter名来定位,所以如果有id属性保证adapter_id唯一,如果id不存在 保证server_id.adapter_name唯一即可访问,
      以在reigstry中查到的object adapter名称为准.
    2. server唯一一个object adapter的逻辑容器出现。






评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值