Ice 对象(Ice Objects)
Ice 对象是一种概念性的实体(或称抽象)。Ice 对象具有以下特征:
. Ice 对象是本地或远地的地址空间中、能响应客户请求的实体。
. 一个Ice 对象可在单个或多个服务器中实例化(后者是冗余方式)。如果
某个对象同时有多个实例,它仍是一个Ice 对象。
. 每个Ice对象都有一个或多个接口。 一个接口是一个对象所支持的一系列
有名称的操作。客户通过调用操作来发出请求。
. 一个操作有零个或更多参数,以及一个返回值。参数和返回值具有明确的类型。参数是有名称的,并且有方向:in 参数由客户初始化,并传给服务器; out 参数由服务器初始化,并传给客户(返回值只是一种特
殊的out 参数)。
. 一个Ice 对象具有一个特殊的接口,称为它的主接口。此外, Ice 对象还可以提供零个或更多其他接口,称为facets (面)。客户可以在某个对象的各个facets 之间进行挑选,选出它们想要使用的接口。
. 每个Ice 对象都有一个唯一的对象标识(object identity)。对象标识是用于把一个对象与其他所有对象区别开来的标识值。Ice 对象模型假定对象标识是全局唯一的,也就是说,在一个Ice 通信域中,不会有两个对
象具有相同的对象标识。
代理(Proxies)
要想与某个Ice 对象联系,客户必须持有这个对象的代理。 代理是客户的地址空间中的一种制品(artifact);对客户而言,代理就是Ice 对象的代表(该对象可能在远地)。一个代理充当的是一个Ice 对象的本地大使:
当客户调用代理上的操作时, Ice run time 会:
1. 定位Ice 对象
2. 如果Ice 对象的服务器没有运行,就激活它
3. 在服务器中激活Ice 对象
4. 把所有in 参数传送给Ice 对象
5. 等待操作完成
6. 把所有out 参数及返回值返回给客户(或在发生错误的情况下抛出异常)
代理封装了完成这一系列步骤所必需的全部信息。特别地,代理包含有:
. 寻址信息:用于让客户端run time 联系正确的服务器
. 对象标识:用于确定服务器中的哪一个对象是请求的目标
. 可选的facet 标识符:用于确定代理所引用的是对象的哪一个facet
直接代理(Direct Proxies)
直接代理是这样一种代理:其内部保存有某个对象的标识,以及它的服务器的运行地址。该地址由以下两项内容完全确定:
. 协议标识符(比如TCP/IP或UDP)
. 针对具体协议的地址(比如主机名和端口号)
间接代理(Indirect Proxies)
间接代理是这样一种代理:其内部保存有某个对象的标识,以及对象适配器名(object adapter name)。要注意,间接代理没有包含寻址信息。为了正确地定位服务器,客户端run time 会使用代理内部的对象适配器名,将其传给某个定位器服务,比如IcePack 服务。然后,定位器会把适配器名当作关键字,在含有服务器地址的表中进行查找,把当前的服务器地址返回给客户。客户端run time 现在知道了怎样联系服务器,就会像平常一样分派(dispatch)客户请求。客户端run time 会通过配置了解怎样去和IcePack 服务联系(就像web 浏览器会通过配置了解要使用哪一个DNS)。
Servants
Ice 对象是一种具有类型、标识,以及寻址信息的概念性实体。
在服务器端提供操作调用的行为的制品叫作servant。一个servant 提供一个或多个Ice 对象的实质内容
实际上,servant 就是服务器开发者编写的类的实例,这些类作为一个或多个Ice 对象的servant、向服务器端run time 进行注册。类的方法对应于Ice 对象的接口上的操作,并且提供这些操作的行为。
"最多一次"语义十分重要,因为这保证了非idempotent 操作可以安全使用。
idempotent 操作是这样的操作:如果执行两次,其效果与执行一次相同。例如, x = 1; 是idempotent 操作:如果我们两次执行该操作,最终结果与执行一次是一样的。另一方面, x++; 不是idempotent 操作:如果我们执行该操作两次,最终结果与我们执行一次不一样。
同步方法调用(Synchronous Method Invocation)
在缺省情况下, Ice 使用的请求分派模型是同步的远地过程调用:操作调用的行为就像是本地过程调用,也就是说,在调用期间,客户线程被挂起,并在调用完成(及它的所有结果可用)时恢复。
异步方法调用(Asynchronous Method Invocation)
Ice 还支持异步方法调用(AMI):客户可以异步地调用操作,也就是说,客户像平常一样使用代理来调用操作,但除了传递通常的参数以外,还要传递一个回调对象,而客户调用会立即返回。一旦操作完成,客户端
端run time 会调用一开始所传递的回调对象上的方法,把操作的结果传给该对象(或在失败时传递异常信息)。服务器无法区分异步调用和同步调用——无论是哪种情况,服务器看到的都只是客户调用了某个对象上的操作。
异步方法分派(Asynchronous Method Dispatch)
异步方法分派(AMD)是AMI 的服务器端等价物。采用异步方法分派,当操作调用到达时,服务器端应用代码会收到通知。但是,服务器端应用不会被迫立即处理请求,而是可以选择延缓处理,从而释放用于处理该请求的执行线程。至此,服务器端应用代码就可以随意做它想做的任何事情了。最后,当操作的结果可用时,服务器端应用代码可以发出一个API 调用,告诉服务器端Ice run time,先前分派的某个请求现在已经完成;这时,操作的结果就会返回给客户。
采用异步分派,数百或数千客户可以阻塞在同一个操作调用中,而又不用在服务器中占用任何线程。
单向方法调用(Oneway Method Invocation)
通信数据只会从客户流向服务器,而不会反向流动。只有对没有返回值、没有输出参数、也不抛出用户异常的操作 ,才能进行单向调用。
成批的单向方法调用(Batched Oneway Method Invocation)
每个单向调用都会向服务器发送一条单独的消息。如果是一系列短小的消息,这样做的开销相当可观:客户和服务器端run time 必须为了每一条消息、在用户模式与内核模式之间切换,同时,在网络层,每条消息还会带来流控制和确认开销。成批的单向调用允许你在一条消息中发送一系列单向调用:每次你调用一个这样的单向操作,调用都会缓冲在客户端run time 中。一旦你累积了所有你想要发送的单向调用,你就发出另外一个API 调用,一次发送所有调用。
数据报调用(Datagram Invocations)
数据报调用具有与单向调用类似的“尽力”语义。但数据报调用要求对象提供UDP 作为传输机制(而单向调用要求提供TCP/IP)
数据报和单向调用一样是不可靠的。但与单向调用不同,数据报调用可能会发生另外一些错误:数据报调用很适用于LAN 上的小消息,在LAN 上,丢失的可能性很小。它们也适用于低延迟比可靠性更重要的情形,比如快速的交互式Internet 应用。
成批的数据报调用(Batched Datagram Invocations)
属性(Properties)
Ice run time 有大量功能都是通过属性来配置的。属性就是“名-值”对,比如Ice.Default.Protocol=tcp。属性通常存储在文本文件中,Ice run time 会对其进行解析,从而配置各种选项,比如线程池尺寸、跟踪级别,以及各种其他的配置参数。
例子hello目录下的config文件,就配置各种属性。
以上是从中文文档中对一些我想比较重要的部分摘抄下来的,其中有几个要点:
1)ice run time
这是ice的核心,客户调用本地代理时,ice run time会开始工作,完成一系列幕后的工作,对用户来说是透明的,各种语言的映射也要由run time来转换。
2)ice对象
以后我在学习slice时,应该可以对ice对象有个更清晰的认识,现在只需知道:Ice 对象是一种具有类型、标识,以及寻址信息的概念性实体。
3)调用模型
Ice提供了同步调用,异步调用,单向调用,数据报调用,批调用,分派模型,线程。这里最关键的是异步两个字,异步的实现使得对大量用户的响应成为可能。
4)绑定模式
直接绑定,间接绑定,这实际就是怎样定位对象的位置。类似corba中的naming service。