本文基于ICE Manual及相关文档就ICE的一些主要特性做一个概览,它不是一个tutorial,不是一个guid,更不是manual。
概览
ICE,Internet Communications Engine,按照官方介绍,是一个支持C++、.Net、Java、Python、Objective-C、Ruby、PHP及ActionScript等语言的分布式程序开发平台。按照我的理解,简单来说它是一个核心功能包装RPC的库。要把这个RPC包装得漂亮,自然而然,对于使用者而言,调用一个远端的接口和调用一个本地的接口没有什么区别,例如:
Object *obj = xxx
obj->sayHello();
ICE包装sayHello
接口,当应用层调用该接口时,ICE发送调用请求到远端服务器,接收返回结果并返回给应用层。ICE在接口提供方面,做到了这一点。
以下,我将逐个给出ICE中的一些工具、组件、特性说明,以展示它作为一个分布式程序开发平台所拥有的能力。到目前为止,所有这些信息均来自于ICE相关文档,总结出来权当为自己服务。
Slice
Slice(Specification Language for Ice)是ICE定义的一种中间语言,其语法类似于C++。对于一个RPC过程而言,例如上面调用远端的sayHello
接口,其主要涉及到调用这个接口的参数和返回值传递,当然接口本身的传递不在话下,ICE为了包装这个过程,其使用了这样一种方式:使用者使用Slice语言描述RPC过程中调用的接口,例如该接口属于哪个类,该接口有哪些参数哪些返回值;然后使用者使用ICE提供的Slice编译器(实际上是一个语言翻译程序)将Slice源码翻译成目标语言。而这个目标语言,则是使用者开发应用程序的开发语言,即上文提到的C++、.Net、Java等。
这些翻译出来的目标代码,就封装了sayHello
底层实现的一切细节。当然事情没有这么简单,但我们目前只需关注简单的这一部分。ICE之所以支持那么多种开发语言,正是Slice立下的功劳。Slice语言本身的语言特性,实际上受限于目标语言的语言特性,例如Slice支持异常,恰是因为Slice转换的所有语言都包含异常这个语法特性。
Slice还有一个重要特性,在于一份Slice源码被翻译出来的目标代码,一般情况是被服务器和客户端同时使用。
开发步骤
使用ICE开发应用程序,其步骤遵循:
- 编写Slice,说明整个RPC中涉及到的接口调用,编译它
- 基于Slice目标代码和ICE库编写Server
- 基于Slice目标带啊和ICE库编写Client
一个例子
有必要展示一个例子,以获得使用ICE开发应用程序的感性认识。这个例子是一个简单的hello world程序,客户端让服务器打印一个字符串。
- 编写Slice
// Printer.ice,Slice源码后缀为ice
module Demo {
interface Printer {
void printString(string s);
};
};
使用ICE提供的程序翻译为C++代码:
$ slice2cpp Printer.ice
得到Printer.cpp和Printer.h。Slice翻译出来的目标代码除了封装RPC交互的一些细节外,最重要的,因为本身Slice文件其实是定义接口,但接口的实现,则需要应用层来做。
- 服务器端使用生成的Printer.cpp/.h,并实现Printer接口
// 翻译出来的Printer.h中有对应于Slice中定义的Printer类,及需要实现的printString接口
class PrinterI : public Printer {
public:
virtual void printString(const string& s, const Ice::Current&) {
count << s << endl;
}
};
- 客户端使用生成的Printer.cpp/.h,通过ICE获得一个
Printer
对象,然后调用其printString
接口
// don't care about this
PrinterPrx printer = PrinterPrx::checkedCast(base);
printer->printString("Hello World!");
使用ICE开发应用程序,整体过程即为以上展示。
概念
ICE包含了很多概念,作为一个开发平台而言,有其专有术语一点不过分,熟悉这些概念可以更容易学习ICE。这里罗列一些关键概念。
服务器端和客户端
ICE中的服务器端和客户端和一般网络程序中的概念不太一样。在若干个交互的网络程序中,我们都很好理解这样一种现象:某个程序有多个角色,它可能是作为A程序的服务器端,也可能是作为B程序的客户端。ICE中的服务器和客户端角色更容易变换。
以Printer例子为例,如果我们的printString
接口有一个回调函数参数(这在ICE中很常见),服务器实现printString
时,当其打印出字符串后,需通过该回调函数通知客户端。这样的回调机制在ICE的实现中,会创建一个新的网络连接,而此时,这个原有的服务器端就变成了原有客户端的客户。当然,你也可以避免这样的情况出现。
ICE Objects/Object Adapter/Facet
对于Printer
例子,一个Printer
对象可以被看作是一个ICE Objects。Object可以说是服务器端提供给客户端的接口。所以在服务器端通常会创建出很多个Object。服务器端使用Object Adapter对象去保存这些Object。例如,一个典型的ICE对象在初始化时可能包含以下代码:
// 创建一个Object Adapter
Ice::ObjectAdapterPtr adapter = communicator()->createObjectAdapter("Hello");
// 创建一个Object,形如Printer
Demo::HelloPtr hello = new HelloI;
// 将Object加入到Object Adapter
adapter->add(hello, communicator()->stringToIdentity("hello"));
Facet是Object的一部分,或者说Object是Facet的一个集合,摘Ice manual中的一句话:
An Ice object is actually a collection of sub-objects known as facets whose types are not necessarily related.
Proxy
Proxy是ICE客户端里的概念。客户端通过Proxy访问服务器端上的Object,通过Proxy调用服务器端Object上提供的接口。在客户端上一般有类似以下代码:
Ice::ObjectPrx base = ic->stringToProxy("SimplePrinter:default -p 10000");
// Printer Proxy
PrinterPrx printer = PrinterPrx::checkedCast(base);
printer->printString("Hello World!");
Proxy又分为几种,包括:
Direct Proxy
Direct Proxy,这里的direct
意指这个proxy访问的object时,是否携带了地址(EndPoint)信息,例如上面例子中SimplePrinter:default -p 10000
就是一个地址。
Indirect Proxy
Indirect Proxy相对Direct Proxy而言,其没有具体的地址,仅仅是一个符号。通常包含两种形式:
- SimplePrinter
- SimplePrinter@PrinterAdapter
为了获取真正的地址,客户端需要一个定位服务(location service)来获取这个符号对应的地址。ICE中提供了一些默认的服务程序,IceGrid就是其中之一,而IceGrid的作用就包括定位具体的地址,即翻译符号地址到具体的地址。
这里Indirect Proxy可以看作一个域名,而Direct Proxy可以看作是IP地址。Indirect Proxy使用时,就需要借助DNS翻译得到域名对应的IP地址。
Fixed Proxy
由于Proxy是用于与服务器端的Object通信的,客户端借助Proxy来访问服务器端的Object,所以Proxy通常都会对应一个真实的网络连接。在ICE中,一般的Proxy于网络连接(Connection)实际上是没有太大关联的。一个Proxy可以没有Connection,也可以在建立这个Connection后又断开之。但是,ICE提供了一种特殊的Proxy,Fixed Proxy,这种Proxy紧密地与一个Connection绑定在一起,其生命周期被强制关联起来。
关于Fixed Proxy可以参看ICE Manual Connection Management。
其他
- AMI
Asynchronous Method Invocation,对于客户端而言,用于表示某个服务器端接口是异步操作,需在Slice中使用metadata来修饰这个接口,例如:
["ami"] void sayHello(int delay)
- AMD
Asynchronous method dispatch,这个针对于服务器端,同样表示这个接口是异步操作,需在Slice中使用metadata来修饰这个接口:
["ami", "amd"] void sayHello(int delay)
通常对于这种异步接口而言,都需要使用Slice metadata ami
和amd
同时修饰。
- idempotent
idempotent是Slice中的概念,同const一样用于修饰某个接口的特性。idempotent表示该接口无论调用多少次,其执行结果都是相同的,例如一般的get
类接口。
- batched invocation
客户端调用服务器端的接口这个动作称为invocation
。就像网络层的数据缓存一样,ICE对于接口调用也可能暂时缓存,当多个提交请求缓存起来后,然后调用刷新接口全部刷新到服务器端,则称为batched invocation
。
服务
ICE除了提供一个库之外,还提供了一些应用程序。这些应用程序本身也是一些服务器,提供了一些方便的功能方便我们开发分布式程序。
Freeze
Freeze用于将Slice对象持久化到数据库中,按照Manual里的说法,它应该是一个编译器,可以生成一些持久化操作的代码。Freeze持久化对象时使用的数据库是Berkeley DB。
Ice has a built-in object persistence service, known as Freeze. Freeze makes it easy to store object state in a database: you define the state stored by your objects in Slice, and the Freeze compiler generates code that stores and retrieves object state to and from a database. Freeze uses Berkeley DB as its database.
FreezeScript有点类似于Rails中的数据库操作工具,可用于操作持久化到数据库中的对象数据。
Ice also offers a tool set collectively called FreezeScript that makes it easier to maintain databases and to migrate the contents of existing databases to a new schema if the type definitions of objects change.
IceBox
IceBox可用于管理服务器中的动态组件。这些动态组件本质上也是提供服务的ICE程序。在形式上,这些组件可以是动态连接库。
IceBox is a simple application server that can orchestrate the starting and stopping of a number of application components. Application components can be deployed as a dynamic library instead of as a process.
IceGrid
IceGrid相当于一个DNS解析服务,可以让服务器不用配置EndPoint,客户端也不用指定服务器的EndPoint,以方便大量的服务器部署。在一般的应用中,我们需要为ICE服务器指定绑定的网络地址(IP和端口),同时也需要为客户端指定服务器端的地址信息。当服务增加到一定数量时,就会存在管理上和配置上的麻烦。而IceGrid则是用于避免这种麻烦,将服务器端和客户端上的地址信息通过一个符号代替,就像我们把Internet上的服务器使用域名来标识一样。
但IceGrid的作用不仅如此,通过配合部署一系列称为IceGrid Node的程序,IceGrid还可以管理各个服务器的启动、关闭、宕机重启等,其中甚至包括负载均衡。
IceGrid provides a facility to activate servers on demand, when a client first invokes an operation. Server activation is taken care of by IceGrid nodes. You must run an IceGrid node on each machine on which you want IceGrid to start servers on demand.
简要介绍可以参看ICE Manual Teach Yourself IceGrid in 10 minutes
Glacier2
Glacier2 is a lightweight firewall traversal solution for Ice applications.
按我的理解,Glacier2就像一个网关服务器。它被部署在服务器和客户端之间,我们的服务器群部署在内网,外网不可访问,然后通过Glacier2,外部网络的客户端就可以访问内网的服务器群提供的服务。
对于服务器的开发而言,使用Glacier2,服务器端不需要做任何改动。客户端需要配置Glacier2服务的地址信息,也需要配置要使用服务器的地址信息。Glacier2通过客户端欲访问的服务器地址,在内网定位到真实的服务器,并转发请求提供服务。
Glacier2支持验证客户端,从这一点看来,它又有点像一个验证服务器。通过验证客户端,以提供被正确授权的客户端以完整服务。
Glacier2的工作过程可以描述为:
When a client invokes an operation on a routed proxy, the client connects to one of Glacier2’s client endpoints and sends the request as if Glacier2 is the server. Glacier2 then establishes an outgoing connection to the client’s intended server in the private network, forwards the request to that server, and returns the reply (if any) to the client. Glacier2 is essentially acting as a local client on behalf of the remote client.
一个Glacier2可服务于若干个客户端和服务器。
详细参看ICE Manual Glacier2
管理
ICE服务器可以提供给外部一定的管理功能,包括:关闭服务器、读取服务器配置。这个功能是通过操作Ice.Admin这个Ice Object来实现的。这个Object包含两个Facet:Process和Property,分别对应于关闭服务器和读取服务器配置功能。
对于需要管理服务器的客户端而言,可以大致通过如下代码来完成:
// 可以通过communicator来获取这个admin object
Ice::ObjectPrx adminObj = ...;
// 获取admin object里的property facet
Ice::PropertiesAdminPrx propAdmin = Ice::PropertiesAdminPrx::checkedCast(adminObj, "Properties");
Ice::PropertyDict props = propAdmin->getPropertiesForPrefix("");
详细参看ICE Manual Administrative Facility
连接管理
前已述及,ICE中的网络连接隐藏于Proxy之下。Proxy有两个接口可以获取这个连接对象:
ice_getConnection
ice_getCachedConnection
例如:
HelloPrx hello = HelloPrx::uncheckedCast(communicator->stringToProxy("hello:tcp -h remote.host.com -p 10000"));
ConnectionPtr conn = hello->ice_getConnection();
ICE隐藏了网络连接的细节。当ICE发现需要建立连接时才会去建立,例如以上例子中当获得一个Proxy时(这里是HelloPrx),ICE并不建立网络连接,当某个时刻通过该Proxy调用服务器端的某个接口时,ICE发现对应的网络连接没有建立,则发起网络连接。
以上例子在获取Proxy时,使用了uncheckCast
,关于checkedCast
和uncheckedCast
,也影响着网络连接的建立逻辑:
On the other hand, if the code were to use a checkedCast instead, then connection establishment would take place as part of the checkedCast, because a checked cast requires a remote call to determine whether the target object supports the specified interface.
关于连接管理,ICE使用了一个称为ACM的机制,即Active connection management。当某个连接非active一段时间后,ICE就会主动关闭此连接。应用层当然可以控制这个行为。
详细参看ICE Manual Connection Management
相关推荐
- **可移植性**:Ice 支持多种操作系统和编程语言,便于跨平台开发。 - **安全性**:支持 SSL/TLS 加密传输,确保数据安全。 - **可扩展性**:松耦合的服务架构易于维护和扩展。 #### 知识点九:Ice 源码包中的第三...
### 分布式ICE介绍 #### 一、分布式系统与ICE:一种灵活且简易的中间件 在探讨ICE之前,我们先来了解下分布式系统及早期的一些中间件平台。分布式系统是指由多台计算机组成,这些计算机通过网络进行通信并协同工作...
综上所述,《ICE 分布式程序设计》这本书不仅为读者提供了 ICE 框架的基本概念和技术细节,而且还通过具体的案例演示了 ICE 如何应用于实际开发之中,对于想要学习分布式系统开发的技术人员来说是非常有价值的参考...
Ice,全称为Internet Communications Engine,是ZeroC公司开发的一款用于分布式编程的框架。它允许开发者在不同的操作系统、网络环境和编程语言之间进行透明的通信。Ice的设计目标是提供一个强大、灵活且易于使用的...
- **第二章:ICE概览** – 深入介绍ICE的架构和技术细节。 - **第三章及之后章节** – 详细讨论ICE的各种高级特性和应用场景。 #### 七、ICE的典型应用场景 - **企业级应用**:ICE常用于构建高可用性的企业级应用,...
根据提供的文档信息,我们可以深入探讨其中的关键知识点,主要包括 ICE 的概览、架构和服务,以及如何通过 ICE 进行分布式程序设计等内容。 ### 冰 (ICE) 概览 #### 1.1 引言 ICE (Internet Communications ...
- **1.1.3 Ice 的架构优势**:讨论了使用Ice进行分布式编程的优势,例如跨平台兼容性、易于扩展性以及高级别抽象能力等。 **1.2 HelloWorld 应用程序** 这一章节通过创建一个简单的HelloWorld应用来介绍Ice的基本...
Ice(Internet Communications Engine)是一个强大的跨平台中间件,用于开发分布式系统。它支持多种编程语言,如C++、Java和Python等,并且能够在不同的操作系统之间进行通信。Ice的设计旨在简化复杂系统的构建过程...
IceBerg概览 IceBerg整合Flink IceBerg整合Hive IceBerg整合Spark 4、存储相关,包含rocksdb、Hbase、BookKeeper、Zookeeper等 5、Hadoop生态圈的学习笔记,主要记录HDFS、MapReduce、Yarn相关读书笔记及源码分析等 ...
### Ice 分布式程序设计概览 #### 一、Ice对象特性详解 Ice对象作为Ice框架中的核心概念,具备以下几个显著特点: 1. **本地或远程的地址空间**:Ice对象既可以存在于本地进程的地址空间中,也可以位于远程服务器...
ICE因其优秀的跨平台性能、可扩展性和低资源消耗,成为追求高性能分布式系统开发的理想选择。然而,对于特定场景或已有技术生态的项目,WCF和Java RMI也有其独特优势。最终,选择合适的中间件平台,需权衡各项因素,...
Ice是一个高性能、可扩展的服务端开发框架,用于构建分布式应用程序。它支持多种编程语言,并且能够跨平台运行,这使得开发者能够在不同的操作系统上构建和部署服务。 #### 1.1 Ice的核心特性 - **跨语言支持**:...
**ICE**(Internet Communications Engine)是一款高性能的中间件系统,主要用于构建分布式应用程序。它提供了一种简单而强大的方式来实现跨平台、跨语言的服务通信。 ##### 1.1.1 ICE架构 ICE采用了一种面向服务...
Ice还提供了一系列的服务来帮助开发者更轻松地构建分布式系统,比如路由、持久性存储、位置透明性等功能。 #### Ice的架构优势 Ice的设计使其能够跨平台运行,具备高性能和可扩展性,同时易于部署和管理。 ### ...
#### 一、Ice概览 **1.1 Ice架构** ##### 1.1.1 冰(Ice)架构 - **术语**:在深入理解Ice架构之前,了解其专业术语至关重要。Ice架构中的几个关键概念包括对象适配器、对象代理、对象工厂等。 - **对象适配器...
Ice 和 Python 的结合为开发者提供了一种高效开发分布式应用的方式。Python 作为一种高级语言,其简洁性和易用性使得它成为许多开发者的选择。 **Hello World—Really!:** 本节通过一个简单的“Hello World”示例...
#### 一、Ice概览 **1.1 Ice架构概述** Ice (Internet Communications Engine) 是一个强大的跨平台框架,用于构建分布式应用程序。其核心特性在于能够支持多种语言(如C++、Java等)之间的无缝通信。 ##### 1.1.1...
- **中间件**:ICE(交互组件引擎)、CORBA(公共对象请求代理体系结构)、DCOM(分布式组件对象模型)等。 - **网络类型**:互联网、移动电话网络、企业网络、工厂网络、校园网络、家庭网络等。 - **特点**: ...
3. **Cache机制**:为提高响应速度,通常会采用复杂的缓存策略,如分布式缓存系统。 4. **需求快速更新**:网站需快速响应用户反馈,实现快速开发、测试、部署的迭代过程。 在架构设计中,涉及以下几个关键方面: ...
- **不涉及**:IceGrid服务的工作机制与实现原理、服务器端和客户端程序的具体开发细节。 - **重点在于**:IceGrid服务的配置方法及其验证手段。 #### 二、IceGrid配置步骤详解 **知识点4:配置文件创建** 1. **主...