ice grid 第一篇
关键点:
(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 第一篇的更多相关文章
- ice grid配置使用第二篇------实际使用
一 首先,启动ice grid 1 修改配置文件 node.cfg,appication.xml 修改registry.cfg 配置注册表信息: IceGrid.Registry.Client. ...
- ImageJ 学习第一篇
ImageJ是世界上最快的纯Java的图像处理程序.它可以过滤一个2048x2048的图像在0.1秒内(*).这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Image ...
- 第一篇 入门必备 (Android学习笔记)
第一篇 入门必备 第1章 初识Android 第2章 搭建你的开发环境 第3章 创建第一个程序--HelloWorld 第4章 使用Android工具 ●Android之父 Android安迪·罗 ...
- Java图像处理最快技术:ImageJ 学习第一篇
ImageJ是世界上最快的纯Java的图像处理程序. 它能够过滤一个2048x2048的图像在0.1秒内(*). 这是每秒40万像素!ImageJ的扩展通过使用内置的文本编辑器和Java编译器的Ima ...
- 从0开始搭建SQL Server AlwaysOn 第一篇(配置域控)
从0开始搭建SQL Server AlwaysOn 第一篇(配置域控) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www.cnb ...
- Python爬虫小白入门(四)PhatomJS+Selenium第一篇
一.前言 在上一篇博文中,我们的爬虫面临着一个问题,在爬取Unsplash网站的时候,由于网站是下拉刷新,并没有分页.所以不能够通过页码获取页面的url来分别发送网络请求.我也尝试了其他方式,比如下拉 ...
- Three.js 第一篇:绘制一个静态的3D球体
第一篇就画一个球体吧 首先我们知道Three.js其实是一个3D的JS引擎,其中的强大之处就在于这个JS框架并不是依托于JQUERY来写的.那么,我们在写这一篇绘制3D球体的文章的时候,应该注意哪些地 ...
- 深入学习jQuery选择器系列第一篇——基础选择器和层级选择器
× 目录 [1]id选择器 [2]元素选择器 [3]类选择器[4]通配选择器[5]群组选择器[6]后代选择器[7]兄弟选择器 前面的话 选择器是jQuery的根基,在jQuery中,对事件处理.遍历D ...
- 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
随机推荐
- Confluence搭建
参见 https://confluence.atlassian.com/display/CONF54/Installing+the+Confluence+EAR-WAR+Edition 下载5.4.4 ...
- 虚拟机 centos 7 nginx安装
1下载vmware 12,并安装.百度即可 2下载centos 7,将其安装在vmware 12中.百度即可,无复杂设置. 3设置vmware 中centos7能上网: a.右键计算机->管理- ...
- socket通信实例
ref: http://www.cnblogs.com/xudong-bupt/archive/2013/12/29/3483059.html http://blog.csdn.net/love_ga ...
- redis1--redis的介绍
(1)持久化数据库的缺点平常我们使用的关系型数据库有Mysql.Oracle以及SqlServer等,在开发的过程中,数据通常都是通过Web提供的数据库驱动来链接数据库进行增删改查.那么,我们日常使用 ...
- Webdriver控制翻页控件,并实现向前向后翻页功能,附上代码,仅供参考,其他类似日期控件的功能可以自己封装
新增输入与选择页面的html源码: <div style="margin-top:-60px;" class="modal-content" id=&qu ...
- 使用NSURLProtocol实现UIWebView的离线缓存
http://blog.csdn.net/youcanping2008/article/details/9240487
- iOS TextField输入框点击键盘时随着键盘上移
-(void)textFieldDidBeginEditing:(UITextField *)textField { CGRect frame = textField.frame; int offse ...
- iosiOSlabel基本使用以及文字自适应
(如果需要的不是使用的属性值如换行形式,可以把对应的属性在程序中书写然后按"command"+鼠标左键点击就可以查看所有属性值) 一label基本设置 self.view.back ...
- 《Windows驱动开发技术详解》之IRP的同步
应用程序对设备的同步异步操作: 大部分IRP都是由应用程序的Win32 API函数发起的.这些Win32 API本身就支持同步和异步操作.例如,ReadFile.WriteFile和DeviceIoC ...
- CentOS中由一般用户切换为root用户
--->http://www.centoscn.com/CentOS/help/2014/0624/3173.html 1.打开终端,提示符为“$”,表明该用户为普通用户,此时,直接输su,回车 ...