关键点:

(1)如果想提高并发的话,还是在一个node上对于同一个application开多个server instance.

1.名词解释

。Replica groups

A replica group is the term for a collection of replicated object adapters. An

application can create any number of replica groups. Each group requires a

unique identifier.

• Nodes

An application must assign its servers to one or more nodes.

• Servers

A server’s description includes a unique name and the path to its executable. It

also lists the object adapters it creates.

• Object adapters

Information about an object adapter includes its endpoints and any wellknown

objects it advertises. If the object adapter is a member of a replica

group, it must also supply that group’s identifier.

• Objects

A well-known object is one that is known solely by its identity. The registry

maintains a global list of such objects for use during locate requests.

IceGrid uses the term descriptor to refer to the description of an application

代理

直接代理;:对象 和 地址 。例如,代理:  SimplePrinter:default -p 10000

间接代理:两种。第一种仅仅包含well-known objects(众所周知对象),例如代理  SimplePrinter 就是对象SimplePrinter的代理。第二种包含对象和对象适配器标识,例如,SimplePrinter@PrinterAdapter

2.一个简单的ice架构(ice registry只提供定位服务)

(1)客户端代码:

Ice::ObjectPrx proxy =

communicator->stringToProxy("factory@EncoderAdapter");//第一步是定位服务,通过括号内的"对象@对象适配器id"找到了代理

Ripper::MP3EncoderFactoryPrx factory =

Ripper::MP3EncoderFactoryPrx::checkedCast(proxy); //第二步是使用代理得到想要的远端对象。是对远端对象的第一次调用

Ripper::MP3EncoderPrx encoder = factory->createEncoder();

(2)配置文件

registry 配置:

/opt/ripper/registry.cfg contains the following properties:(前五个必选)

IceGrid.InstanceName=inputtest   //如果不写。默认是IceGrid

IceGrid.Registry.Client.Endpoints=tcp -p 4061

IceGrid.Registry.Server.Endpoints=tcp

IceGrid.Registry.Internal.Endpoints=tcp

IceGrid.Registry.Data=/opt/ripper/registry

IceGrid.Registry.DynamicRegistration=1

IceGrid.Registry.AdminPermissionsVerifier=IceGrid/NullPermissionsV

erifier

IceGrid.Registry.AdminCryptPasswords=../etc/passwd //这个选项倒是很有意思,可以设置操作admin的权限

client配置文件:

Ice.Default.Locator=IceGrid/Locator:tcp -h registryhost -p 4061 (在没有写IceGrid的名字的情况下)

server配置,opt/ripper/server.cfg

EncoderAdapter.AdapterId=EncoderAdapter (对象适配器id)

EncoderAdapter.Endpoints=tcp  //不写端口地址,表明系统自动分配端口

Ice.Default.Locator=IceGrid/Locator:tcp -h registryhost -p 4061

(3)启动

启动registry

icegridregistry --Ice.Config=/opt/ripper/registry.cfg

启动server

/opt/ripper/bin/server     --Ice.Config=/opt/ripper/server.cfg

3 使用ice registry来管理server(xml和node)

3.1 使用xml文件描述server,使用node

为了使用icegridadmin管理工具,我们使用xml配置sever文件:

<icegrid>

<application name="Ripper">

<node name="Node1">

<server id="EncoderServer"

exe="/opt/ripper/bin/server"

activation="on-demand">

<adapter name="EncoderAdapter"

id="EncoderAdapter"

endpoints="tcp"/>

</server>

</node>

</application>

</icegrid>

事实上,以上的描述文件会生成一个server的配置文件如下,由node生成(文件位置在类似/opt/ripper/node/servers/EncoderServer/config/config):

# Server configuration

Ice.Admin.ServerId=EncoderServer

Ice.Admin.Endpoints=tcp -h 127.0.0.1

Ice.ProgramName=EncoderServer

# Object adapter EncoderAdapter

EncoderAdapter.Endpoints=tcp

EncoderAdapter.AdapterId=EncoderAdapter

Ice.Default.Locator=IceGrid/Locator:default -p 4061

# Registry properties

IceGrid.Registry.Client.Endpoints=tcp -p 4061

IceGrid.Registry.Server.Endpoints=tcp

IceGrid.Registry.Internal.Endpoints=tcp

IceGrid.Registry.AdminPermissionsVerifier=IceGrid/NullPermissionsV

erifier

IceGrid.Registry.Data=/opt/ripper/registry

# Node properties

IceGrid.Node.Endpoints=tcp

IceGrid.Node.Name=Node1

IceGrid.Node.Data=/opt/ripper/node

IceGrid.Node.CollocateRegistry=1  //标明registry和node在一个进程中

Ice.Default.Locator=IceGrid/Locator:tcp -p 4061

因为使用协同的registry和node,所以一个命令可以启动registry和node

icegridnode --Ice.Config=/opt/ripper/config

说明:(1)如果没有标明adapter id,那么默认生成id名字为:EncoderServer.EncoderAdapter

3.2 增加节点

(1)server配置

<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>

(2)node配置

IceGrid.Node.Endpoints=tcp

IceGrid.Node.Name=Node2

IceGrid.Node.Data=/opt/ripper/node

Ice.Default.Locator=IceGrid/Locator:tcp -h registryhost -p 4061

(3)客户端

缺陷就是每个server上一个不同的object adapter id,需要进行选择。(这对于增删节点等都很麻烦)

非直接代理:

• factory@EncoderServer1.EncoderAdapter

• factory@EncoderServer2.EncoderAdapter

string adapter;

if ((rand() % 2) == 0)

adapter = "EncoderServer1.EncoderAdapter";

else

adapter = "EncoderServer2.EncoderAdapter";

Ice::ObjectPrx proxy =

communicator->stringToProxy("factory@" + adapter);

Ripper::MP3EncoderFactoryPrx factory =

Ripper::MP3EncoderFactoryPrx::checkedCast(proxy);

Ripper::MP3EncoderPrx encoder = factory->createEncoder();

4 well-known objects(众所周知对象)

4.1  概念

有两种类型的简介代理:一种指定对象标识和对象适配器标志(object@object_adapter_id) ;一种仅仅指定对象标志。后者称为众所周知代理(well-known proxy),它指向well-known object(众所周知对象)。

可以通过以下几个地方声明:

XML文件。          (statically in descriptors,)   

icegrid admin的编程接口           • programmatically using IceGrid’s administrative interface,

使用 ice admin工具动态添加         • dynamically using an IceGrid administration tool.

下面是一个例子,well-known对象和它们的代理

Identity Proxy

Object1 Object1:tcp -p 10001

Object2 Object2@TheAdapter

Object3 Object3

4.2 生成well-known对象

(1)xml文件中

<icegrid>

<application name="Ripper">

<node name="Node1">

<server id="EncoderServer"

exe="/opt/ripper/bin/server"

activation="on-demand">

<adapter name="EncoderAdapter"

id="EncoderAdapter"

endpoints="tcp">

<object identity="EncoderFactory"

type="::Ripper::MP3EncoderFactory"/>

</adapter>

</server>

</node>

</application>

</icegrid>

(2)通过编程接口

接口api说明如下,

module IceGrid {

interface Admin {

...

void addObject(Object* obj)

throws ObjectExistsException,

DeploymentException;

void updateObject(Object* obj)

throws ObjectNotRegisteredException,

DeploymentException;

void addObjectWithType(Object* obj, string type)

throws ObjectExistsException,

DeploymentException;

void removeObject(Ice::Identity id)

throws ObjectNotRegisteredException,

DeploymentException;

...

};

};

编程实现,

Ice::ObjectAdapterPtr adapter =

communicator->createObjectAdapter("EncoderAdapter");

Ice::Identity ident =

communicator->stringToIdentity("EncoderFactory");

FactoryPtr f= new FactoryI;

Ice::ObjectPrx factory = adapter->add(f, ident);

IceGrid::AdminPrx admin = // ...

try {

// admin->addObject(factory); // OOPS!,要求首先激活object adapter

admin->addObjectWithType(factory, factory->ice_id());

} catch (const IceGrid::ObjectExistsException &) {

admin->updateObject(factory);

}

(3)

icegridadmin --Ice.Config=/opt/ripper/config

>>> object add "EncoderFactory@EncoderAdapter"

4.3 使用ice query查找 well-known objects

(1)接口说明:

module IceGrid {

enum LoadSample {

LoadSample1,

LoadSample5,

LoadSample15

};

interface Query {

idempotent Object* findObjectById(Ice::Identity id);

idempotent Object* findObjectByType(string type);

idempotent Object* findObjectByTypeOnLeastLoadedNode(

string type, LoadSample sample);

idempotent Ice::ObjectProxySeq findAllObjectsByType(

string type);

idempotent Ice::ObjectProxySeq findAllReplicas(Object* proxy);

};

};

(2)示例,

一个含有两个well-known objects的例子

<icegrid>

<application name="Ripper">

<node name="Node1">

<server id="EncoderServer1"

exe="/opt/ripper/bin/server"

activation="on-demand">

<adapter name="EncoderAdapter"

endpoints="tcp">

<object identity="EncoderFactory1"

type="::Ripper::MP3EncoderFactory"/>

</adapter>

</server>

</node>

<node name="Node2">

<server id="EncoderServer2"

exe="/opt/ripper/bin/server"

activation="on-demand">

<adapter name="EncoderAdapter"

endpoints="tcp">

<object identity="EncoderFactory2"

type="::Ripper::MP3EncoderFactory"/>

</adapter>

</server>

</node>

</application>

</icegrid>

客户端查找,

1)使用findAllObjectsByType函数

Ice::ObjectPrx proxy =

communicator->stringToProxy("IceGrid/Query");

IceGrid::QueryPrx query = IceGrid::QueryPrx::checkedCast(proxy);

Ice::ObjectProxySeq seq;

string type = Ripper::MP3EncoderFactory::ice_staticId();

seq = query->findAllObjectsByType(type);

if (seq.empty()) {

// no match

}

Ice::ObjectProxySeq::size_type index = ... // random number

Ripper::MP3EncoderFactoryPrx factory =

Ripper::MP3EncoderFactoryPrx::checkedCast(seq[index]);

Ripper::MP3EncoderPrx encoder = factory->createEncoder();

2)使用findObjectByTypeOnLeastLoadedNode函数

Ice::ObjectPrx proxy =

communicator->stringToProxy("IceGrid/Query");

IceGrid::QueryPrx query = IceGrid::QueryPrx::checkedCast(proxy);

Ice::ObjectPrx obj;

string type = Ripper::MP3EncoderFactory::ice_staticId();

obj = query->findObjectByTypeOnLeastLoadedNode(type,

IceGrid::LoadSample1);

if (!obj) {

// no match

}

Ripper::MP3EncoderFactoryPrx factory =

Ripper::MP3EncoderFactoryPrx::checkedCast(obj);

Ripper::MP3EncoderPrx encoder = factory->createEncoder();

到底怎样才是well-known对象?

1.1 replica group(对象适配器复制集群)

(1)   概念

一个复制集群是一组复制的对象适配器;有一个唯一的标识。

一个复制集群被确定之后,他的标识就可以被用在间接代理中替代适配器标识;比如,一个标识为PrinterAdapters的复制集群可以被用在如下的代理:

SimplePrinter@PrinterAdapters

(2)示例

<replica-group id="ReplicatedAdapter">

<load-balancing type="adaptive" load-sample="5"  n-replicas="2"/>

</replica-group>

load-balancing type 表示负载均衡策略;

load-sample 负载采样时间间隔,以分钟计;

n-replicas  返回两个负载最小的对象适配器的端点地址

负载平衡策略包括四种:Random ,Adaptive,Round Robin,Ordered。

(3)问题

采样的时候,linux系统采样的是load average,这样当机器cpu数目不同时,岂不是无法有效利用cpu了?

问题:

(1)既然registry location服务,那么是不是说一个client连接上之后,请求只会被发送到一个node的server上?没错。

但是通过设置,可以指定server,这样就可以发送到不同的node上的server 了

(2) adapter_ = communicator->createObjectAdapter(name); //objectadapter名字

  Ice::PropertiesPtr properties = communicator->getProperties();

  const string& locator = properties->getProperty("Ice.Default.Locator");

  LOG(INFO, "locator: " << locator);

  BunnyConf::instance().set_locator(locator);



  Ice::ObjectPtr object = new HandlerI(); //ice对象

  adapter_->add(object, communicator->stringToIdentity("M")); // 这个ice对象的标识是“M”

  adapter_->activate();

(3)当使用registry 时,object id 可以同时使用object:tcp -p 10001 和  object@adapter 两种形式

(4)replica-group意思?

(5)ice box代替了原来的server,包含程序的真正入口。它可以包含多个service,即多个真正的服务。

貌似有了ice box后,server就是ice box ,详细来说,就是 ice box id。

但是server 又可以包含 ice box

(6)对象适配器的意思

顾名思义,还是对象,不过改变了形态,

(7)icebox   service entry 后边的参数的规定是--name=value这种形式的视为communicator的属性,其余才视为start的参数。可是事实上input服务中是可以通过args读取到这种类型的参数的

规定:Any arguments following the entry point specification are examined. If an

argument has the form --name=value, then it is interpreted as a property definition

that appears in the property set of the communicator passed to the service

start operation. These arguments are removed, and any remaining arguments are

passed to the start operation in the args parameter.

start函数:

void start(string name,

Ice::Communicator communicator,

Ice::StringSeq args)

ice grid 第一篇的更多相关文章

  1. ice grid配置使用第二篇------实际使用

    一    首先,启动ice grid 1 修改配置文件 node.cfg,appication.xml 修改registry.cfg 配置注册表信息: IceGrid.Registry.Client. ...

  2. ImageJ 学习第一篇

    ImageJ是世界上最快的纯Java的图像处理程序.它可以过滤一个2048x2048的图像在0.1秒内(*).这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Image ...

  3. 第一篇 入门必备 (Android学习笔记)

    第一篇 入门必备 第1章 初识Android 第2章 搭建你的开发环境 第3章 创建第一个程序--HelloWorld 第4章 使用Android工具   ●Android之父 Android安迪·罗 ...

  4. Java图像处理最快技术:ImageJ 学习第一篇

    ImageJ是世界上最快的纯Java的图像处理程序. 它能够过滤一个2048x2048的图像在0.1秒内(*). 这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Ima ...

  5. 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)

    从0开始搭建SQL Server AlwaysOn 第一篇(配置域控) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnb ...

  6. Python爬虫小白入门(四)PhatomJS+Selenium第一篇

    一.前言 在上一篇博文中,我们的爬虫面临着一个问题,在爬取Unsplash网站的时候,由于网站是下拉刷新,并没有分页.所以不能够通过页码获取页面的url来分别发送网络请求.我也尝试了其他方式,比如下拉 ...

  7. Three.js 第一篇:绘制一个静态的3D球体

    第一篇就画一个球体吧 首先我们知道Three.js其实是一个3D的JS引擎,其中的强大之处就在于这个JS框架并不是依托于JQUERY来写的.那么,我们在写这一篇绘制3D球体的文章的时候,应该注意哪些地 ...

  8. 深入学习jQuery选择器系列第一篇——基础选择器和层级选择器

    × 目录 [1]id选择器 [2]元素选择器 [3]类选择器[4]通配选择器[5]群组选择器[6]后代选择器[7]兄弟选择器 前面的话 选择器是jQuery的根基,在jQuery中,对事件处理.遍历D ...

  9. 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

随机推荐

  1. C#采用OpenXml给word里面插入图片

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  2. selinux策略开发

    所用软件: 1.setools -->seaudit  读取日志以确定所需权限 2.Reference Policy  -->  https://github.com/TresysTech ...

  3. Android PagerAdapter的用法

    转http://blog.csdn.net/look85/article/details/8563906 在写这个之前,真心需要吐槽一下…关于Android开发中,PageAdapter的用法在网上能 ...

  4. SPOJ 705 New Distinct Substrings

    后缀数组.按照排序完的后缀一个一个统计.每一个后缀对答案做出的贡献为:n-SA[i]-height[i]. #pragma comment(linker, "/STACK:102400000 ...

  5. MFC中修改默认启动对话框方法

    // CMyAppEApp 初始化 BOOL CMyAppEApp::InitInstance(){// 如果一个运行在 Windows XP 上的应用程序清单指定要// 使用 ComCtl32.dl ...

  6. nodejs全局安装与本地安装区别

    本地安装 1. 将安装包放在 ./node_modules 下(运行 npm 命令时所在的目录),如果没有 node_modules 目录,会在当前执行 npm 命令的目录下生成 node_modul ...

  7. hdu_1848_Fibonacci again and again(博弈sg函数)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1848 题意:给你3堆石子,每次只能取fibonacci数的石子,问先手是否能赢 题解:SG函数模版题 ...

  8. LeetCode OJ 160. Intersection of Two Linked Lists

    Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...

  9. 使用 HTML5 input 类型提升移动端输入体验(键盘)

    在最近的项目中,策划老是要求我们弹出各种类型的键盘,特别是在iOS下,例如输入帐号的时候,不应该支持输入中文,该输入纯数字的时候就应该谈数字键盘等.个人觉得这些都是我们平时开发很少意识到的,虽然有些刁 ...

  10. docker log 文件 清理

    1 查看docker log 文件位置  docker inspect *** 2 定时清理 runcate -s 0 /var/lib/docker/containers/*/*-json.log