Zeroc Ice grid 研究学习

原创
2015/07/08 22:03
阅读数 8.5K

一、概念

slice: ice提供了自己的接口定义语言。用来定义rpc的接口和对象。

ice.object: rpc调用的接口必须继承自ice.Object

servant:ice.Object的实例化对象叫做servant,rpc调用的就是servant对象,因此servant需要线程安全

endpoints:客户端rpc调用servant的地址

icebox:servant的容器

icenode:icebox的容器

registry:注册中心,负责管理icenode的注册,负责和发布。

二、部署

步骤:

  1. 启动registry

  2. 启动node,注册到registry

  3. 将代码部署到node服务器上

  4. 将应用描述文件应用到registry上,node上将自动启动application

三、配置文件

registry配置文件一个:registry.cfg

node配置文件n个:node1.cfg, node2.cfg

应用描述文件app.xml

配置文件详情:

registry.cfg

# grid实例名
IceGrid.InstanceName=SzcIceGrid
#客户端连接到注册中心的地址
IceGrid.Registry.Client.Endpoints=tcp -p 4061
IceGrid.Registry.Server.Endpoints=tcp
IceGrid.Registry.Internal.Endpoints=tcp
IceGrid.Registry.PermissionsVerifier=SzcIceGrid/NullPermissionsVerifier
IceGrid.Registry.AdminPermissionsVerifier=SzcIceGrid/NullPermissionsVerifier
#注册中心数据保存路径,需要手动创建文件夹
IceGrid.Registry.Data=/data/shizc/Desktop/ice/registry
IceGrid.Registry.DynamicRegistration=1
Ice.Admin.InstanceName=AdminInstance
Ice.Admin.ServerId=Admin

node1.cfg

# 注册中心地址
Ice.Default.Locator=SzcIceGrid/Locator:tcp -h 192.168.7.7 -p 4061
#node名
IceGrid.Node.Name=node1
IceGrid.Node.Endpoints=tcp
#node存储路径
IceGrid.Node.Data=/data/shizc/Desktop/ice/nodes/node1
IceGrid.Node.Output=/data/shizc/Desktop/ice/nodes/node1
IceGrid.Node.CollocateRegistry=0
#IceGrid.Node.Trace.Replica=2
#IceGrid.Node.Trace.Activator=3
#IceGrid.Node.Trace.Adapter=3
#IceGrid.Node.Trace.Server=3

node2.cfg

# 注册中心地址
Ice.Default.Locator=SzcIceGrid/Locator:tcp -h 192.168.7.7 -p 4061

IceGrid.Node.Name=node2
IceGrid.Node.Endpoints=tcp
IceGrid.Node.Data=/data/shizc/Desktop/ice/nodes/node2
IceGrid.Node.Output=/data/shizc/Desktop/ice/nodes/node2
IceGrid.Node.CollocateRegistry=0
#IceGrid.Node.Trace.Replica=2
#IceGrid.Node.Trace.Activator=3
#IceGrid.Node.Trace.Adapter=3
#IceGrid.Node.Trace.Server=3

app.xml

<icegrid>
  <application name="FileSystemApp">
    <properties id="MultiThreaded" >
      <property name="Ice.PrintStackTraces" value="1" ></property>
      <property name="IceSSL.Trace.Security" value="2" ></property>
      <property name="Ice.ThreadPool.Client.Size" value="2" ></property>
      <property name="Ice.ThreadPool.Client.SizeMax" value="50" ></property>
      <property name="Ice.ThreadPool.Server.Size" value="10" ></property>
      <property name="Ice.ThreadPool.Server.SizeMax" value="100" ></property>
      <property name="IceBox.InheritProperties" value="1" ></property>
      <property name="Ice.Override.ConnectTimeout" value="5000" ></property>
      <property name="Ice.Override.Timeout" value="10000" ></property>
      <property name="IceBox.Trace.ServiceObserver" value="1" ></property>
      <property name="Ice.Default.LocatorCacheTimeout" value="300" ></property>
      <property name="Ice.BackgroundLocatorCacheUpdates" value="1" ></property>
    </properties>
    <!-- 配置模板 -->
    <server-template id="FileSystemServerIceBoxTemplate">
        <parameter name="index" default="0"></parameter>
        <!-- exe指定java启动 -->
        <icebox id="FileSystemServerIceBox${index}" exe="java" activation="on-demand" >
          <properties>
            <properties refid="MultiThreaded" />
          </properties>
          <option>-Xmx512M</option>
          <!-- icebox启动main方法 -->
          <option>IceBox.Server</option>
          <!-- 开发的代码路径 -->
          <env>CLASSPATH=.:/usr/share/java/*:/data/shizc/Desktop/ice/bin</env>
          <!-- entry指定icebox启动的service, replica-group指定endpoints组 -->
          <service name="FilesystemService" entry="service.FilesystemService">
            <adapter name="FilesystemService" id="FilesystemService${index}" endpoints="default" replica-group="FilesystemServiceRep" ></adapter>
          </service>
        </icebox>
    </server-template>
    
    <replica-group id="FilesystemServiceRep">
      <load-balancing type="round-robin" n-replicas="0" />
      <!-- 指定servant的名字 -->
      <object identity="RootDir" type="::filesystem::Directory"></object>
      <object identity="iamfile" type="::filesystem::File"></object>
    </replica-group>
    <!-- 每个node定义2个icebox -->
    <node name="node1">
      <server-instance template="FileSystemServerIceBoxTemplate" index="11"></server-instance>
      <server-instance template="FileSystemServerIceBoxTemplate" index="12"></server-instance>
    </node>
    <node name="node2">
      <server-instance template="FileSystemServerIceBoxTemplate" index="21"></server-instance>
      <server-instance template="FileSystemServerIceBoxTemplate" index="22"></server-instance>
    </node>
  </application>
</icegrid>

四、启动

  1. icegridregistry --Ice.Config=registry.cfg

  2. icegridnode --Ice.Config=node1.cfg

  3. icegridnode --Ice.Config=node2.cfg

  4. icegridadmin --Ice.Config=node1.cfg

    登陆后

    application add app.xml

五、代码

定义slice:

[["java:package:com.asto"]]
module filesystem{
	interface Node{
		string name();
	};
	
	exception GenericError{
		string reason;
	};
	
	sequence<string> Lines;
	
	interface File extends Node{
		Lines read();
		void write(Lines text) throws GenericError;
	};
	
	sequence<Node*> NodeSeq;
	
	interface Directory extends Node{
		NodeSeq list();
	};
	
	interface FileSys{
		Directory* getRoot();
	};
	
};

通过eclipse插件或命令slice2java转换成java类

实现Directory接口和File接口

package servant;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import com.asto.filesystem.NodePrx;
import com.asto.filesystem.NodePrxHelper;
import com.asto.filesystem._DirectoryDisp;

import Ice.Current;

public class DirectoryI extends _DirectoryDisp {

	public static Ice.ObjectAdapter _adapter;
	public String _name;
	public DirectoryI _parent;
	public List<NodePrx> _content = new ArrayList<NodePrx>();

	public DirectoryI(String _name, DirectoryI _parent) {
		super();
		this._name = _name;
		this._parent = _parent;
		Ice.Identity theId = Ice.Util.stringToIdentity(_parent == null ? "RootDir" : UUID.randomUUID().toString());
		_adapter.add(this, theId);
		// 自身的代理
		NodePrx theNode = NodePrxHelper.uncheckedCast(_adapter.createProxy(theId));
		// 把自己添加到父目录的子节点中
		if (_parent != null) {
			_parent.addChild(theNode);
		}
	}

	@Override
	public NodePrx[] list(Current __current) {
		System.out.println("[DirectoryI]invoke list @" + Thread.currentThread().getName());
		NodePrx[] retList = new NodePrx[_content.size()];
		retList = _content.toArray(retList);
		return retList;
	}

	@Override
	public String name(Current __current) {
		System.out.println("[DirectoryI]invoke name @"+ Thread.currentThread().getName());
		return _name;
	}

	void addChild(NodePrx child) {
		System.out.println("[DirectoryI]invoke addChild @"+ Thread.currentThread().getName());
		_content.add(child);
	}

}


package servant;

import java.util.UUID;

import com.asto.filesystem.GenericError;
import com.asto.filesystem.NodePrx;
import com.asto.filesystem.NodePrxHelper;
import com.asto.filesystem._FileDisp;

import Ice.Current;

public class FileI extends _FileDisp {
	public static Ice.ObjectAdapter _adapter;
	public String _name;
	public DirectoryI _parent;
	public String[] _lines;

	public FileI(String _name, DirectoryI _parent) {
		super();
		this._name = _name;
		this._parent = _parent;
		assert(_parent != null);
		String identiyName = UUID.randomUUID().toString();
		if("README".equalsIgnoreCase(_name)){
			identiyName = "iamfile";
		}
		System.out.println("FileI'identiy:"+identiyName);
		Ice.Identity theId = Ice.Util.stringToIdentity(identiyName);
		_adapter.add(this, theId);
		NodePrx theNode = NodePrxHelper.uncheckedCast(_adapter.createProxy(theId));
		_parent.addChild(theNode);
	}

	@Override
	public String[] read(Current __current) {
		System.out.println("[FileI]invoke read @"+ Thread.currentThread().getName());
		return _lines;
	}

	@Override
	public void write(String[] text, Current __current) throws GenericError {
		System.out.println("[FileI]invoke write @"+ Thread.currentThread().getName());
		_lines = text;
	}

	@Override
	public String name(Current __current) {
		System.out.println("[FileI]invoke name @"+ Thread.currentThread().getName());
		return _name;
	}

}

这2个接口的实现类中都包含了一个Ice.ObjectAdapter, servant要通过adapter对外提供服务。

在构造方法中,将自身的实例(servant)添加进adapter中。

实现Icebox的的Service接口,

package service;

import com.asto.filesystem.GenericError;

import Ice.Communicator;
import IceBox.Service;
import servant.DirectoryI;
import servant.FileI;

public class FilesystemService implements Service {
	private Ice.ObjectAdapter _adapter;
	@Override
	public void start(String name, Communicator communicator, String[] args) {
		_adapter = communicator.createObjectAdapter(name);
		DirectoryI._adapter = _adapter;
		FileI._adapter = _adapter;
		DirectoryI root = new DirectoryI("/", null);
		FileI file = new FileI("README", root);
		String[] text = new String[] { "This file system contain a collection of poetry." };
		try {
			file.write(text);
		} catch (GenericError e) {
			System.err.println(e.reason);
		}

		DirectoryI coleridge = new DirectoryI("Coleridge", root);
		file = new FileI("Kubla_Khan", coleridge);
		text = new String[] { "In Xanadu did Kubla Khan", "A stately pleasure-dome decree:", "Where Alph, the sacred river, ran", "Through caverns measureless to man", "Down to a sunless sea." };
		try {
			file.write(text);
		} catch (GenericError e) {
			System.err.println(e.reason);
		}

		_adapter.activate();
		System.out.println("FileSystemServer adapter activate @" + Thread.currentThread().getName());
	}

	@Override
	public void stop() {
		System.out.println(getClass().getName() + " _adapter destroy @" + Thread.currentThread().getName());
		if(_adapter != null){
			_adapter.destroy();
		}
	}

}

FileSystemService在app.xml中配置到Icebox中。

client调用:

public static void main(String[] args){
		Ice.Communicator ic  = null;
		try{
			ic = Ice.Util.initialize(args);
//			Ice.ObjectPrx basePrx = ic.stringToProxy("iamfile");
//			FilePrx detailPrx = FilePrxHelper.checkedCast(basePrx);
			Ice.ObjectPrx basePrx = ic.stringToProxy("RootDir");
			DirectoryPrx detailPrx = DirectoryPrxHelper.checkedCast(basePrx);
			if(detailPrx == null){
				System.err.println("filePrx is null");
				System.exit(1);
			}
			String name = detailPrx.name();
			System.out.println("fileName is :" + name);
			
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if(ic != null){
				ic.shutdown();
				ic.waitForShutdown();
				ic.destroy();
			}
		}
		
		
	}

client运行需要添加一个配置文件,指定registry地址

client.cfg

Ice.Default.Locator=SzcIceGrid/Locator:tcp -h 192.168.7.7 -p 4061

在运行client的时候指定配置文件

java com.client.Client --Ice.Config=client.cfg

六、引用

参考了《ZeroC Ice权威指南》和 http://blog.csdn.net/lihuayong/article/details/9901417

展开阅读全文
打赏
0
8 收藏
分享
加载中
更多评论
打赏
0 评论
8 收藏
0
分享
返回顶部
顶部