?? rmi
字號:
遠程對象激活
----------------------------------------------------------------------
----------
第 7 章
主題:
概述
激活協(xié)議
“可激活”遠程對象的實現(xiàn)模型
激活接口
.1 概述
分布式對象系統(tǒng)被設(shè)計為支持長期存在的持久對象。假設(shè)這些系統(tǒng)將由成千(也
許成萬)個這樣的對象組成,則對象的實現(xiàn)在無限期的時間段內(nèi)被激活并保持活
動狀態(tài)是不合理的。這將占用寶貴的系統(tǒng)資源。另外,客戶機需要保存對對象的
持久引用的能力,這樣在一個系統(tǒng)崩潰后可以重新建立對象之間的通訊,因為通
常對一個分布對象的引用只有當對象處于活動狀態(tài)時才有效。
對象激活是一種用來提供對對象持久引用和管理對象實現(xiàn)的執(zhí)行的機制。在 RMI
中,激活允許對象根據(jù)需要開始執(zhí)行。當訪問(通過方法調(diào)用)“可激活”遠程
對象時,如果該遠程對象當前尚未執(zhí)行,則系統(tǒng)將在適當?shù)?Java 虛擬機中開始
該對象的執(zhí)行。
7.1.1 術(shù)語
活動 (active) 對象是在某些系統(tǒng)的 Java 虛擬機中被實例化并被導出的遠程對
象。非活動對象在虛擬機中尚未被實例化(或?qū)С觯茏兂苫顒訝顟B(tài)的遠程
對象。激活就是將非活動對象轉(zhuǎn)化為活動對象的過程。激活要求對象與一臺虛擬
機相關(guān)聯(lián),而這將可能需要將該對象的類加載到虛擬機中,同時該對象也恢復其
持久狀態(tài)(如果有)。
在 RMI 系統(tǒng)中,我們使用了惰性激活。惰性激活就是將一個對象的激活延遲到客
戶機第一次使用該對象時(即第一次方法調(diào)用時)。
7.1.2 惰性激活
遠程對象的惰性激活是用不完善遠程引用(有時稱為不完善塊)實現(xiàn)的。對遠程
對象的不完善遠程引用在第一次調(diào)用對象的方法時,“完善”為活動對象的引用
。每個不完善引用均保持一個持久句柄(激活標識符)和對目標遠程對象的瞬態(tài)
遠程引用。遠程對象的激活標識符包含足夠的信息來使第三方激活該對象。瞬態(tài)
引用是對可用來聯(lián)系執(zhí)行對象的主動遠程對象的“活動”引用。
在不完善引用中,如果對遠程對象的活引用為空,則不認為目標對象是主動的。
在方法調(diào)用中,不完善引用(對該對象)將加入激活協(xié)議以獲得“活”引用,該
引用是對新激活的對象的遠程引用(例如單路傳送 (unicast) 的遠程引用)。一
旦不完善引用得到活引用,則不完善引用將把方法調(diào)用傳給底層的遠程引用,而
該遠程引用又將方法調(diào)用傳給遠程對象。
具體的說,遠程對象的 stub 包含一個“不完善”遠程引用類型,該類型既包括:
遠程對象的激活標識符,又包括
“活”引用(可能為空),其中包含遠程對象的“活動”遠程引用類型(例如,
帶有單路傳送語義的遠程引用類型)。
----------------------------------------------------------------------
----------
注意 - RMI 系統(tǒng)對遠程調(diào)用保留“至多一次”語義。換句話說,對可激活或單路
傳送遠程對象的調(diào)用將至多發(fā)送一次。因此,如果對遠程對象的調(diào)用失敗(由拋
出的 RemoteException 異常表示),則客戶機將得到如下保證:遠程方法的執(zhí)行
不會超過一次,甚至根本就不執(zhí)行。
7.2 激活協(xié)議
在遠程方法調(diào)用期間,如果目標對象的“活”(live) 引用是未知的,則不完善引
用將使用激活協(xié)議。激活協(xié)議包括下列幾個實體:不完善引用、激活器、Java 虛
擬機中的激活組和被激活的遠程對象。
激活器(通常每個主機有一個)是一個實體,負責激活,它是:
將激活標識符映射到激活對象所需信息(對象的類、位置 -- URL 路徑 -- 從該
處可加載類、對象可能需要用于自舉 (bootstrap) 的特定數(shù)據(jù)等)的信息數(shù)據(jù)庫,及
Java 虛擬機的管理器,它啟動虛擬機(必要時)并將對象激活請求(和必要的信
息一起)傳送到遠程虛擬機中正確的激活組。
注意:激活器始終將激活標識符到活動對象的當前映射保存在緩存中,這樣就無
需為每個激活請求而查詢該組。
激活組(每個 Java 虛擬機中一個)是這樣的實體,它接收對激活 Java 虛擬機
中對象的請求并將激活的對象返給激活器。
激活協(xié)議如下所示。不完善引用使用一個激活標識符并調(diào)用激活器(內(nèi)部 RMI 接
口)來激活與該標識符關(guān)聯(lián)的對象。激活器查找對象的激活描述符(先前已注冊
)。對象的描述符包括:
對象的組標識符(指定對象激活時所處的虛擬機),
對象的類名,
URL 路徑,從該處加載對象的類代碼,
特定于對象的已編組的初始化數(shù)據(jù)(例如,初始化數(shù)據(jù)可能是包含對象持久狀態(tài)
的文件的名稱)。
如果應(yīng)容納該對象的激活組存在,則激活器將激活請求傳送到該組。如果激活組
不存在,則激活器將啟動虛擬機以執(zhí)行激活組,然后將激活請求傳送到該組。
激活組將加載對象的類并用特定的構(gòu)造函數(shù)來實例化該對象。此構(gòu)造函數(shù)帶多個
參數(shù),包括先前注冊的激活描述符。
對象完成激活時,激活組將把已編組對象引用傳回激活器,然后該激活器記錄激
活標識符和激活引用對,并將活動(活)引用返給不完善引用。隨后,不完善引
用(在 stub 內(nèi))通過活動引用將方法調(diào)用直接傳給遠程對象。
----------------------------------------------------------------------
----------
注意 - 在 JDK 中,RMI 提供激活系統(tǒng)接口的實現(xiàn)。要使用激活,必須首先運行
激活系統(tǒng)守護進程 (daemon) rmid。
7.3 “可激活”遠程對象的實現(xiàn)模型
為了使可通過激活標識符訪問的遠程對象不受時間影響,開發(fā)人員必須做到:
為該遠程對象注冊一個激活描述符
在對象的類中包含一個專用構(gòu)造函數(shù),當 RMI 系統(tǒng)激活可激活對象時將調(diào)用它。
可用以下幾種方法來注冊激活描述符 (ActivationDesc):
調(diào)用類 Activatable 的靜態(tài) register 方法
用 Activatable 類的第一個或第二個構(gòu)造函數(shù)創(chuàng)建“可激活”對象
顯式地導出“可激活”對象。該過程可用 Activatable 的第一個或第二個 expo
rtObject 方法實現(xiàn),其參數(shù)為 ActivationDesc、Remote 對象的實現(xiàn)和端口號。
對于特定對象,只可用上述三種方法之一來注冊激活對象。有關(guān)如何實現(xiàn)可激活
對象的示例,請參閱后面的“構(gòu)造可激活遠程對象”。
7.3.1 ActivationDesc 類
ActivationDesc 含有激活對象所需的信息。它包含對象的激活組標識符、對象的
類名、加載對象代碼的 codebase 路徑(或 URL)及 MarshalledObject(可包含
每次激活期間所用的對象特定初始化數(shù)據(jù))。
激活過程中將查詢在激活系統(tǒng)中注冊的描述符以獲取有關(guān)的信息,從而用于重新
創(chuàng)建或激活對象。對象的描述符中的 MarshalledObject 將作為第二個參數(shù)傳給
遠程對象的構(gòu)造函數(shù),以供激活過程使用。
package java.rmi.activation;
public final class ActivationDesc implements java.io.Serializable
{
public ActivationDesc(String className, String codebase,
java.rmi.MarshalledObject data)
throws ActivationException;
public ActivationDesc(String className, String codebase,
java.rmi.MarshalledObject data,
boolean restart)
throws ActivationException;
public ActivationDesc(ActivationGroupID groupID,
String className,
String codebase,
java.rmi.MarshalledObject data,
boolean restart);
public ActivationDesc(ActivationGroupID groupID,
String className,
String codebase,
java.rmi.MarshalledObject data);
public ActivationGroupID getGroupID();
public String getClassName();
public String getLocation();
public java.rmi.MarshalledObject getData()
public boolean getRestartMode();
}
ActivationDesc 的第一個構(gòu)造函數(shù)構(gòu)造一個對象的對象描述符,這個對象的類是
className(可從 codebase 路徑加載),它的初始化信息(已編組形式)為 d
ata。如果使用這種形式的構(gòu)造函數(shù),則對象的組標識符缺省為該虛擬機 Activa
tionGroup 的當前標識符。具有相同 ActivationGroupID 的所有對象都將在同一
虛擬機中被激活。如果當前組是非活動的或無法創(chuàng)建缺省組,則將拋出 Activat
ionException。如果 groupID 為 null,則將拋出 IllegalArgumentException。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -