2011年(264)
分类: 系统运维
2011-05-24 08:11:51
1、 提供适用于异构环境的面向对象中间件平台
2、 提供一组完整的特性,支持广泛的领域中的实际的分布式应用开发
3、 避免不必要的复杂性使的平台易于学习与使用
4、 提供一种在网络带宽、内存使用和CPU开销方面都很高效的实现
5、 提供一种具有内建安全性的实现使它适用于不安全的公共网络
ICE对象
1、 ICE对象是本地或远地的地址空间、能响应客户请求的实体
2、 一个ICE对象可在单个或多个服务器中实例化
3、 每个ICE对象都有一个或多个接口。一个接口是一个对象所支持的一系列有名称的操作,客户通过调用操作来发出请求
4、 一个操作有零个或更多参数,以及一个返回值。参数和返回值具有明确的类型。参数是有名称的并且有方向。In参数由客户初始化并传给服务器。Out参数由服务器初始化并传给客户
5、 一个ICE对象具有一个特殊的接口称它为主接口。此外ICE 对象还可以提供零个或更多其他接口称为facets(面)。客户可以在某个对象的各个facets之间进行挑选选出它们想要使用的接口
6、 每个ICE对象都有一个唯一的对象标识。对象标识是用于把一个对象与其他对象区别开来的标识值。ICE对象模型假定对象标识是全局唯一的即一个ICE通信域中不会有两个对象具有相同的对象标识
串行代理
代理中的信息可以用串的形式表示。例如
SimplePrinter:default –p 10000
其中ICE提供了一些API调用允许你把代理转换成它的串化形式这样就可以将代理存储到数据库或文本文件中。
直接代理
其内部保存有某个对象的标识,以及它的服务器的运行地址。
1、 协议标识符(比如TCP/IP或UDP)
2、 针对具体协议的地址(比如主机名和端口号)
直接绑定VS间接绑定
把代理里面的信息解析为协议—地址对的过程称为绑定。
直接绑定用于直接代理,而间接绑定用于间接代理。
使用直接代理你可以不用为了定位服务器而进行的额外查找,但如果服务器被移到其他机器上,它就不再能工作。而另外一方面如果移动了服务器间接代理也能够继续工作。
2011-5-23 笔记
Servants
在服务器端提供操作调用的行为的制品叫做servant。一个servant提供一个或多个ICE对象的实质内容(或体现这些对象)。实际上servant就是服务器开发者编写的类的实例。这些类作为一个或多个ICE对象的servant向服务器端run time进行注册。类的方法对应于ICE 对象的接口上的操作,并且提供这些操作的行为。
同步方法调用
在默认情况下ICE使用的请求分派模型是同步的远地过程调用:操作调用的行为就像是本地过程调用。即在调用期间客户线程被挂起并在调用完成时恢复
异步方法调用
ICE还支持异步方法调用(AMI):客户可以异步调用操作,即客户像平常一样使用代理来调用操作,但除了传递通常的参数以外还要传递一个回调对象,而客户调用会立即返回。
一旦操作完成客户端run time会调用一开始所传递的回调对象上的方法,把操作的结果传给该对象(或在失败时传递异常信息)。
服务器无法区分异步调用和同步调用,无论是哪种情况服务器看到的都只是客户调用了某个对象上的操作。
对于客户而言同步和异步分派是透明的,即客户不知道服务器会选择同步还是异步方式对请求进行处理。
属性
ICE RUN TIME有大量功能都是通过属性来配置的。属性就是:名—值。比如
Ice.Default.Protocol = tcp
属性通常存储在文本文件中。Ice run time会对其进行解析,从而配置各种选项比如线程池尺寸、跟踪级别以及各种其他的配置参数。
Slice(ICE规范语言)
每个ICE的对象都有一个接口,该接口具有一些操作。接口、操作还有客户及服务器间交换的数据类型都是用Slice语言定义的。这就是相当于一个客户-服务器的合约。Slice定义由一个编译器编译成特定编程语言的API。即与你所定义的接口和类型对应的那一部分API会自动生成代码。
ICE协议
ICE提供了一种RPC协议,既可以把TCP/IP也可以把UDP用作底层传输机制。此外ICE还允许SSL用作传输机制。这样客户与服务器间的所有通信都可以加密。
ICE协议定义了:
一些消息类型,比如请求和答复类型
协议状态机,确定客户与服务器以怎样的序列交换不同的消息类型
编码规则,确定在线路上怎么样表示数据的类型
每种消息类型的头,其中有这样的细节:消息类型、消息尺寸、所使用的协议及编码版本
对象持久
ICE还有内建的对象持久服务叫Freeze。能够在数据库中存储对象状态:你用Slice定义你的对象要存储的状态,Freeze编译器会生成代码用以在数据库中存储和取回对象状态。
ICE在架构上提供的好处
1、 面向对象的语义
ICE在线路上完全保留了面向对象的范型。所有的操作调用都使用迟后绑定。
2、 支持同步和异步的消息传递
ICE提供了同步和异步的操作调用和分派,并且通过IceStorm提供了发布-订阅消息传递机制。可以根据应用的需求来选择通信模型,而不必把你的应用硬塞进某种模型里
3、 支持多个接口
4、 机器无关性
客户及服务器与底层机器架构屏蔽开。
5、语言无关性
客户和服务器可以分别部署。客户和服务器所用Slice定义建立两者之间的接口合约,这样的定义也是唯一需要达成一致的东西
6、实现无关性
客户不知道服务器是怎么样实现对象的。在客户端部署之后服务器的实现可以改变
7、 操作系统无关
ICE API完全是可移植的
8、 线程支持
其API是线程安全的
9、传输机制无关性
ICE目前采用了TCP/IP和UDP作为传输协议。客户和服务器代码都不需要了解底层的传输机制
10、安全性
通过SSL强加密。通信非常安全
11、内建的持久机制
创建持久的对象实现
总之:ICE提供了一流的分布式计算开发和部署环境。
你可以用最小、最简单的API去做你想要做的事情。这样我们能够轻松学习和理解ICE平台用更短的时间进行开发
这是如此简单以致于只需要用几天时间学习ICE就可以用它开发工业级的分布式应用了
第三章节
第一步:编写Slice定义
编写作何ICE应用的第一步都是要编写一个SLICE定义,其中含有应用所用的各个接口
interface Printer
{
void printString(string s);
};
保存为Printer.ice文件中。
第二步:编写使用Java的ICE应用
编译用于JAVA的Slice定义
要创建我们的JAVA应用第一步就是要编译这个slice定义,生成相应的JAVA的骨架和代理
在UNIX上可以这样编译:
$mkdir generated
$slice2java --output-dir generated Printer.ice
--output-dir 选项告诉编译器要把生成的文件放到generated目录下面。这样生成的文件就不会搅乱工作目录。
编写和编译服务器
要实现我们的Printer接口,我们就必须创建一个servant类。Servant类的名字是它们的接口的名称加上一个I后缀,所以我们的servant类叫做PrinterI
public class PrinterI extends _PrinterDisp {
public void printString(String s,Ice.Current current) {
System.out.println(s);
}
}
_PrinterDisp 是由slice2java编译器生成的是一个抽象类。
服务器代码的其他部分在一个叫作server.java源文件中
public class Server
{
public static void
main(String[] args)
{
int status = 0;
Ice.Communicator ic = null;
try
{
ic = Ice.Util.initialize(args);
Ice.ObjectAdapter adapter = ic.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000");
Ice.Object object = new PrinterI();
adapter.add(object, ic.stringToIdentity("SimplePrinter"));
adapter.activate();
ic.waitForShutdown();
}
catch(Exception e)
{
e.printStackTrace();
status = 1;
}
if(ic != null)
{
try
{
ic.destroy();
}
catch(Exception e)
{
System.err.println(e.getMessage());
status = 1;
}
}
System.exit(status);
}
}
OK到此就可以编译服务器代码
$mkdir classes
$javac –d classes –classpath classes:$ICEJ_HOME/lib/Ice.jar -source 1.4 Server.java PrinterI.java generated/*.java
客户代码
public class Client
{
public static void
main(String[] args)
{
int status = 0;
Ice.Communicator ic = null;
try
{
ic = Ice.Util.initialize(args);
Ice.ObjectPrx base = ic.stringToProxy("SimplePrinter:default -p 10000");
Demo.PrinterPrx printer = Demo.PrinterPrxHelper.checkedCast(base);
if(printer == null)
{
throw new Error("Invalid proxy");
}
printer.printString("Hello World!");
}
catch(Ice.LocalException e)
{
e.printStackTrace();
status = 1;
}
catch(Exception e)
{
System.err.println(e.getMessage());
status = 1;
}
if(ic != null)
{
try
{
ic.destroy();
}
catch(Exception e)
{
System.err.println(e.getMessage());
status = 1;
}
}
System.exit(status);
}
}
客户端编译就会像
$javac –d classes –classpath classes:$ICEJ_HOME/lib/Ice.java –source 1.4 Client.java PrinterI.java generated/*.java
开始运行服务器和客户
在一个单独窗口中启动服务器:
$java Server
在另外一个窗口运行客户
$java Client
编写一个ICE应用的步骤:
1、 编写Slice定义并编译它
2、 编写服务器并编译它
3、 编写客户并编译它
以下是python版本
$vi Printer.ice
#ifndef SIMPLE_ICE
#define SIMPLE_ICE
module Demo
{
interface Printer
{
void printString(string s);
};
};
#endif
服务器的代码
import sys, traceback, Ice
Ice.loadSlice('Printer.ice')
import Demo
class PrinterI(Demo.Printer):
def printString(self, s, current=None):
print s
status = 0
ice = None
try:
ic = Ice.initialize(sys.argv)
adapter = ic.createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -p 10000")
object = PrinterI()
adapter.add(object, ic.stringToIdentity("SimplePrinter"))
adapter.activate()
ic.waitForShutdown()
except:
traceback.print_exc()
status = 1
if ic:
# Clean up
try:
ic.destroy()
except:
traceback.print_exec()
status = 1
sys.exit(status)
相应的客户端代码
import sys, traceback, Ice
Ice.loadSlice('Printer.ice')
import Demo
status = 0
ice = None
try:
ic = Ice.initialize(sys.argv)
base = ic.stringToProxy("SimplePrinter:default -p 10000")
printer = Demo.PrinterPrx.checkedCast(base)
if not printer:
raise RuntimeError("Invalid proxy")
printer.printString("Hello World!")
except:
traceback.print_exc()
status = 1
if ic:
# Clean up
try:
ic.destroy()
except:
traceback.print_exc()
status = 1
sys.exit(status)
感觉实现的思路与java一样~