- 遠端呼叫
- 請求-應答協議
- 基於 UDP 資料包的實現
- 通訊原語
- 協議訊息結構
- 請求-應答協議的故障模型
- 重複丟棄請求訊息
- 丟失應答訊息
- 歷史
- 互動協議的型別
- 基於 TCP 流的實現
- 基於 UDP 資料包的實現
- 遠端過程呼叫 RPC
- 介面程式設計
- RPC 呼叫語義
- 透明性
- RPC 的實現
- 遠端方法呼叫 RMI
- RMI 的設計
- 物件模型
- 分散式物件
- RMI 實現
- RMI 模組
- RMI 軟體
- 伺服器和客戶程式
- RMI 的設計
- 參考資料
遠端呼叫
在請求-應答協議中描述了一個基於訊息傳遞的範型,該協議支援在客戶/伺服器的訊息雙向傳輸,此類協議為遠端操作的執行請求提供了相關的底層支援。遠端過程呼叫(RPC)將傳統的過程呼叫模型擴充套件到分散式系統,允許客戶程式透明地呼叫在伺服器程式中的過程。這些伺服器程式執行在不同的程序中,通常位於不同於客戶端的計算機中。基於物件的程式設計模型被擴充套件以後,允許不同程序執行的物件透過遠端方法呼叫(Remote Method Invocation, RMI)彼此通訊。RMI 是對本地方法呼叫的擴充套件,它允許一個程序物件呼叫另外一個程序物件的方法。相比遠端過程呼叫而言,RMI 的優勢是把物件引用擴充套件到全域性分散式環境中,因此可以把物件引用作為引數。
請求-應答協議
基於 UDP 資料包的實現
請求-應答協議用於支援典型客戶/伺服器互動中角色和資訊的轉換,通常情況下請求-應答通訊是同步、可靠的,在來自伺服器端的應答到達之前客戶端程序是阻塞,同時從伺服器端的應答是對客戶端程序的一個有效的確認。儘管目前很多客戶-伺服器交換的實現採用的是 TCP 流的形式,但也可以透過在 UDP 資料包中的傳送(send)和接收(receive)操作來描述。建立在資料包上的協議避免了像 TCP 流那樣不必要的開銷,主要原因有:
- 應答緊跟在請求之後,所以確認資訊是多餘的;
- 一個 TCP 連線的建立除了需要一對請求和應答之外,還涉及兩對額外的訊息;
- 對於大部分只有少數的引數和結果的呼叫來說,流控制是多餘的。
通訊原語
請求-應答協議將請求和應答進行匹配,用於提供傳輸保證,如果使用 UDP 資料包就必須透過請求-應答協議提供傳輸保證。它基於三個通訊原語:doOperation、getRequest、sendReply,他們的工作流程如下圖所示。客戶使用 doOperation 方法來呼叫遠端操作,方法引數指定遠端伺服器、待呼叫的操作以及操作請求的附加資訊,其結果是包含應答內容的位元組陣列。在傳送請求訊息之後,doOperation 方法透過呼叫 receive 方法接收應答訊息,並從應答資訊中提取結果返回給呼叫者,呼叫者在伺服器執行所請求的操作和傳輸應答資訊給客戶端程序之前是阻塞的。伺服器程序透過 getRequest 方法獲得請求訊息,當伺服器呼叫了指定的操作時,它會透過 sendReply 方法向客戶傳送應答訊息。當客戶端接收到應答訊息時,原來的 doOpration 方法就會解除阻塞,客戶端程序繼續執行。
呼叫 doOperation 方法的客戶將引數編碼(marshal)進一個位元組陣列,並從返回的字元陣列中解碼(unmarshal)出結果。doOperation 方法的第一個引數是類 RemoteRef 的一個例項,該例項描述了遠端伺服器的一個引用,提供了獲取相關伺服器的網際網路地址和埠號的方法。doOperation 方法向某個伺服器傳送請求資訊,該伺服器的網路 IP 地址、埠號在以引數形式出現的遠端引用中指定。
// sends a request message to the remote server and returns the reply.
// The arguments specify the remote server, the operation to be invoked and the arguments of that operation.
public byte[] doOperation (RemoteRef s, int operationId, byte[] arguments);
// acquires a client request via the server port.
public byte[] getRequest();
// sends the reply message to the client at its Internet address and port.
public void sendReply (byte[] reply, InetAddress clientHost, int clientPort);
協議訊息結構
請求應答協議訊息結構如下表所示,如果需要提供類似於可靠訊息傳遞或一些額外特性,就需要每一個訊息必須有唯一的訊息識別符號。透過訊息識別符號才可以引用訊息,它由 requestld 和傳送程序的識別符號(如 IP 地址和 port),第一部分使該識別符號對於傳送者來說是唯一的,第二部分則使其在分散式系統中是唯一的。
引數 | 資料型別 | 含義 |
---|---|---|
messageType | int(0=Request, 1= Reply) | 訊息的型別 |
requestId | int | 資訊識別符號,用於檢測是否為當前請求訊息的結果 |
remoteReference | RemoteRef | 遠端物件引用 |
operationId | int or Operation | 被呼叫操作的識別符號 |
arguments | array of bytes | 操作引數 |
請求-應答協議的故障模型
如果這三個通訊原語操作基於 UDP 資料包實現,則它們會遇到存在遺漏故障、沒有保證訊息按照其傳送順序進行傳輸的故障。考慮到伺服器故障或請求、應答訊息被丟棄的情況,doOperation 方法在等待獲取伺服器應答訊息時使用超時(timeout)機制,當出現超時所採取的方案依賴於所能提供傳輸保證。超時的原因可能是請求或應答訊息丟失,對於後者該操作將被執行,為了避免訊息丟失的可能性,doOperation 方法會重複地傳送請求訊息直到它收到應答。或在已有理由相信延遲是因為伺服器未作應答而不是丟失了請求訊息是,最終 doOperation 方法返回時會以未接收到結果的異常告訴客戶。
重複丟棄請求訊息
當請求訊息重複傳輸時,伺服器可能不止一次地接收到該訊息,例如伺服器可能接收第一個請求訊息但執行時產生超時事件,這就導致伺服器為同樣的請求而不止一次地執行某個操作。為了避免這種情況,該協議設計能識別來自同一客戶的帶有相同請求識別符號的連續訊息,並過濾掉重發的訊息。如果伺服器還沒有傳送應答訊息,它就無須採取特殊行動。
丟失應答訊息
冪等操作(idempotent operation)指的是:它重複執行的效果與它僅執行一次的效果相同,例如向集合中新增一個元素的操作是冪等操作,而給一個序列新增一個項就不是冪等操作。當伺服器收到一個重複的請求訊息時若已經傳送了應答訊息,除非它儲存了原先執行的結果,否則它需要再次執行這個操作來獲得該結果。一些伺服器會不止一次地執行它們的操作並每次都獲得相同的結果,而如果一個伺服器上的操作都是冪等操作,就沒有必要去採取特殊措施避免操作的多次執行。
歷史
對於要求重新傳輸應答而不需要重新執行操作的伺服器來說,可以使用歷史,術語“歷史”通常指的是包含已傳送的(應答)訊息記錄的結構。歷史的內容包含請求識別符號、訊息和訊息被髮送到的客戶的識別符號,當客戶程序請求伺服器時讓伺服器重新傳輸應答訊息。如果伺服器不能確定何時不再需要重新傳輸訊息,則歷史的記憶體開銷將會變得很大。
由於客戶每次只能傳送一個請求,伺服器可以將每個請求解釋成客戶對上一次應答訊息的確認,因此歷史中只需要包含傳送給每個客戶的最晚的應答訊息。然而當伺服器有大量的客戶時,客戶程序終止時不會為它所接到的最晚的應答訊息傳送應答確認,因此歷史中的訊息在一個有限的時間段以後會被丟棄,給伺服器歷史機制設定帶來挑戰。
互動協議的型別
為了實現多種型別的請求行為,可以使用三種協議:請求(R)協議、請求-應答(RR)協議、請求-應答-確認應答(RRA)協議,這些協議能夠在出現通訊故障時產生不同的行為。
互動協議 | 說明 |
---|---|
R 協議 | 客戶端向伺服器端傳送一個單獨的請求訊息,之後客戶端可以立即繼續執行而無須等待應答訊息,該協議基於 UDP 資料包實現。 |
RR 協議 | RR 協議不要求特殊的確認訊息,伺服器的應答訊息看成是客戶端請求訊息的一個確認,反之亦然。透過帶有重新過濾的請求重複傳輸和在重新傳輸的歷史中儲存應答訊息的方式,可以遮蔽 UDP 帶來的通訊故障。 |
RRA 協議 | RRA 的應答訊息中包含了來自於被確認的應答訊息的 requestld,使伺服器能從歷史中刪除相應的條目,requestld 被視為在所有的 requestld 中比其更小的應答訊息的確認。 |
基於 TCP 流的實現
資料包有長度的限制,但是訊息中的引數或結果可能是任意長度的,所以資料包不適應於透明 RMI 或 RPC 系統的使用。因為 TCP 流可以傳輸任意長度的引數和結果,因此基於 TCP 流的實現可以避免多包協議。使用 TCP 協議就能保證可靠的傳輸請求訊息和應答訊息,而且流控制機制可以傳遞大量的引數和結果而不需採用特殊措施來避免大規模的接收。
遠端過程呼叫 RPC
遠端過程呼叫 RPC 實現了高階的分佈透明性,實現了呼叫遠端機器上的程式就像這些程式在本地的地址空間中一樣的效果。底層 RPC 系統隱藏了分散式環境重要的部分,包括對引數和結果的編碼和解碼、訊息傳遞以及保留過程呼叫要求的語義。
介面程式設計
模組之間的通訊可以依靠模組間的過程呼叫,為了控制模組之間可能的互動,必須為每一個模組定義顯式的介面,來指定可供其他模組訪問的過程和變數。實現後的模組就隱藏了除介面以外的所有資訊,只要模組的介面保持相同,模組的實現就可以隨意改變而不影響到模組的使用者。在分散式程式中模組能夠執行在不同的程序中,使用介面可以和具體的實現之間實現分離:
- 程式設計師只需要關心服務介面提供的抽象而不需要去關注它們的實現細節;
- 程式設計師無需知道程式語言或者實現服務的底層平臺;
- 只要介面(外部檢視)保持不變,實現可以改變。
服務介面的定義受分散式底層的基礎設施的影響,對於執行在某個程序中的客戶模組去訪問另一個程序中模組的變數是不可能的,因此服務介面不能指定到變數的直接訪問。在本地過程呼叫中使用的引數傳遞機制,不適用於呼叫者和過程在不同的程序中的情況,尤其是不支援傳遞引用。而且一個過程的地址對於一個遠端過程是無效的,這些約束對於介面規範的定義語言有很重要的影響。只要程式語言包含適當的定義介面的表示法,並允許將輸入和輸出引數對映成該語言中正常使用的引數,RPC 機制可以整合到某種程式語言中。介面定義語言(Interface definition languages, IDL)提供了一種定義介面的表示法,允許以不同語言實現過程以便相互呼叫。
RPC 呼叫語義
可以透過不同的方式實現 doOperation 以提供不同的傳輸保證,主要的選擇有:
doOperation 實現方式 | 說明 |
---|---|
重發請求訊息 | 是否要重傳直到接收到應答或者認定伺服器已經出現故障為止 |
過濾重複請求 | 是否要在伺服器過濾掉重複的請求 |
重傳結果 | 是否要在伺服器上儲存結果訊息的歷史 |
將這些選擇組合使用導致了呼叫者所見到的 RPC 可靠性的各種可能語義,如下表所示。對於本地方法呼叫的語義是恰好一次,意味著每個方法都恰好執行一次。
呼叫語義 | 重傳 | 過濾重複請求 | 重新執行過程或重傳應答 |
---|---|---|---|
或許 | 否 | 不適用 | 不適用 |
至少一次 | 是 | 否 | 重新執行過程 |
至多一次 | 是 | 是 | 重傳應答 |
在或許呼叫語義中,遠端方法可能執行一次或者根本不執行。或許語義對應了沒有使用任何容錯措施的時候,此時被呼叫的過程的執行情況無法被確定,它可能會遇到以下的故障型別:
或許呼叫語義故障 | 說明 |
---|---|
遺漏故障 | 如果呼叫或結果訊息丟失 |
系統崩潰 | 由於包含遠端物件的伺服器出現故障 |
在至少一次呼叫語義中,呼叫者可能收到返回的結果,也可能收到一個異常。在收到返回結果的情況下,呼叫者知道該方法至少執行過一次,而異常資訊則通知它沒有接收到執行結果。該語義可以透過重發請求訊息來實現,這樣可以遮蔽呼叫或結果訊息的遺漏故障。此時可能會遇到以下兩種型別的故障,如果能設計伺服器中的介面中所有的方法都是冪等操作的話,則至少一次呼叫語義是可以接受的。
- 由於包含遠端物件的伺服器故障而引起的系統崩潰;
- 隨機故障,重發呼叫訊息時遠端物件可能會接收到這一訊息並多次執行某一方法,結果導致儲存或返回了錯誤的值。
在至多一次呼叫語義中,呼叫者可以接收返回的結果,也可以接收一個異常。在接收返回結果的情況下,呼叫者知道該方法恰好執行過一次,而異常資訊則通知呼叫者沒有收到執行結果。此時方法要麼執行過一次,要麼根本沒有執行。至多一次呼叫語義可以透過使用所有的容錯措施來實現,重傳可以遮蔽所有呼叫或結果訊息的遺漏故障。
透明性
透明性的要求指導使遠端過程呼叫與本地過程呼叫盡可能相似,使得二者在語法上沒有差別,所有對編碼和訊息傳遞過程的必要呼叫都對編寫呼叫的程式設計師面隱藏起來。RPC 致力於提供最少的位置透明性和訪問透明性,由於涉及網路、另一臺計算機和另一個程序,它比本地呼叫更容易失敗。不論選擇上述哪種呼叫語義,總有可能接收不到結果,而且 RPC 延遲要比本地呼叫的延遲大好幾個數量級。在出現故障的情況下,不可能判別故障是源於網路的失效還是遠端伺服器程序的故障。遠端過程呼叫也要求另外的引數傳遞型別,IDL 的設計者也會面臨遠端呼叫是否應該透明的抉擇。當前比較一致的意見是,從語法一致的角度看 RPC 應該是透明的,它和本地呼叫的不同應該表現在它們的介面上。
RPC 的實現
RPC 通常透過請求-應答協議實現,通常選擇至少一次或至多一次呼叫語義。對於服務介面中的每個方法,訪問服務的客戶端包含了一個存根過程(stub procedure)。存根過程的行為對客戶端來說就像一個本地過程,它把過程識別符號和引數編碼成一個請求訊息,透過它的通訊模組傳送給伺服器。當應答訊息返回時,存根過程將對結果進行解碼。
伺服器端包含分發器程式、伺服器存根過程和服務過程,它們的功能如下表所示,客戶和伺服器的存根過程及分發器程式可以透過介面編譯器從服務的介面定義中自動生成。
伺服器端元件 | 說明 |
---|---|
分發器程式 | 根據請求訊息中的過程識別符號選擇一個伺服器存根過程 |
伺服器存根過程 | 對請求訊息中的引數解碼,然後呼叫相應的服務過程,並把返回值編碼成應答訊息 |
服務過程 | 服務介面中過程的具體實現 |
遠端方法呼叫 RMI
遠端方法呼叫(Remote Method Invocation, RMI) 將遠端呼叫擴充套件到了分散式物件,在 RMI 中訪問物件能夠呼叫位於潛在的遠端物件上的方法。RMI 和 RPC 的共性如下:
- 都支援介面程式設計;
- 都是基於請求-應答協議構造的,並能提供一系列如最少一次、最多一次呼叫語義;
- 都提供相似程度的透明性,本地呼叫和遠端呼叫採用相同的語法。
RMI 在複雜的分散式應用和服務的程式設計中帶來一些額外的功能,首先程式設計師能夠在分散式系統軟體開發中使用所有的物件導向程式設計的功能,以及相關物件導向的設計方法和相關的工具的使用。急著在基於 RMI 系統中的所有物件都有唯一的物件引用,物件引用可以當做引數進行傳遞,因此 RMI 比 RPC 提供了更為豐富的引數傳遞語義RMI 使得程式設計師不僅能夠透過值進行輸入或輸出引數傳遞,而且還能透過物件引用進行傳遞。
RMI 的設計
物件模型
RMI 的關鍵設計問題涉及物件模型,尤其是實現從物件到分散式物件的轉變。一個物件導向程式由相互互動的物件的集合組成,每個物件又由一組資料和一組方法組成。一個物件與其他物件通訊是透過呼叫其他物件的方法、傳遞引數和接收結果進行的,但在一個分散式物件系統中,物件的資料僅透過它的方法被訪問。
物件模型 | 說明 |
---|---|
物件引用 | 透過物件引用訪問物件,為了呼叫物件的一個方法,需要給出物件引用和方法名和必要的引數 |
介面 | 介面在無須指定其實現的情況下提供了一系列方法基調的定義(即引數的型別、返回值和異常) |
動作 | 動作由呼叫另一個物件的方法的物件啟動,可以包含執行方法所需的附加資訊(引數) |
異常 | 該模組在不使程式碼複雜化的情況下清晰處理錯誤條件,每個方法都清楚地列出產生異常的錯誤條件 |
無用單元收集 | 當不再需要物件時,提供一種手段釋放其佔用的空間 |
接收者執行適當的方法,然後將控制返回給呼叫物件,方法的呼叫會產生三個結果:
- 接收者的狀態會發生改變;
- 可以例項化一個新的物件;
- 可能會在其他物件中發生其他方法呼叫。
分散式物件
程式的狀態被劃分為幾個單獨的部分,每個部分都與一個物件關聯,所以在分散式系統中可以很自然地將物件物理地分佈在不同的程序或計算機中。分散式物件系統可以採用客戶-伺服器體系結構,物件由伺服器管理,客戶透過遠端方法呼叫來呼叫它們的方法。分散式物件的呼叫流程如下,此時可能會有一連串的相關呼叫,因此伺服器中的物件也可以成為其他伺服器中物件的客戶。
- 客戶呼叫一個物件方法的請求,以訊息的形式傳送到管理該物件的伺服器;
- 在伺服器端執行物件的方法來完成該呼叫,並將處理的結果透過另一個訊息返回給客戶。
將客戶和伺服器物件分佈在不同的程序中,可提高封裝性。此時一個物件的狀態只能被該物件的方法訪問,這意味著不可能讓未經授權的方法作用於該物件狀態。將分散式程式的共享狀態視為一個物件集的另一個好處是,物件可以透過 RMI 來訪問,其中有些物件既可以接收遠端呼叫又可以接收本地呼叫。不管是否在同一臺計算機內,不同程序中的物件之間的方法呼叫都被認為是遠端方法呼叫,在同一程序中的稱為本地方法呼叫。
以下是一些關於分散式物件模型的組成部分:
分散式物件模型 | 說明 |
---|---|
遠端物件 | 能夠接收遠端呼叫的物件 |
遠端物件引用 | 它是一個可以用於整個分散式系統的識別符號,指向某個唯一的遠端物件,訪問遠端物件的遠端物件引用就可以呼叫其擁有的方法 |
遠端介面 | 每個遠端物件都有一個遠端介面,指定哪些方法可以被遠端呼叫 |
動作 | 一個動作是由方法呼叫啟動的,涉及一連串相關呼叫的物件可能處於不同的程序或不同的計算機中,當呼叫跨越了程序或計算機邊界的時候就要使用 RMI |
無用單元收集 | 通常透過已有的本地無用單元收集器和一個執行分散式無用單元收集的附加模組的協作來實現 |
異常 | 任何遠端呼叫都可能會因為被呼叫物件的種種原因而失敗,因此遠端方法呼叫應該能夠引起異常 |
遠端物件引用與本地物件引用主要在以下兩方面類似:
- 呼叫者透過遠端物件引用指定接收遠端方法呼叫的遠端物件;
- 遠端物件引用可以作為遠端方法呼叫的引數和結果傳遞。
RMI 實現
RMI 模組
完成遠端方法呼叫涉及幾個獨立的物件和模組,如下表所示:
RMI 模組 | 說明 |
---|---|
通訊模組 | 兩個相互協作的通訊模組執行請求-應答協議,在客戶和伺服器之間傳遞請求和應答訊息 |
遠端引用模組 | 負責在本地物件引用和遠端物件引用之間進行翻譯,並負責建立遠端物件引用 |
伺服器 | 是一個提供了遠端物件主體的類的例項,處理由相應的骨架傳遞的遠端請求 |
其中通訊模組只使用訊息型別、requestld 和被呼叫物件的遠端引用作為訊息的內容。伺服器端通訊模組為被呼叫的物件類選擇分發器,傳輸其本地引用。伺服器存活於伺服器端的程序中,當遠端物件被例項化時,就會生成一個伺服器,它們可以一直使用到不再需要遠端物件為止。每個程序中的遠端引用模組都有一個遠端物件表,記錄著該程序的本地物件引用和遠端物件引用的對應關係,包括該程序擁有的所有遠端物件和每個本地代理。遠端引用模組的動作如下:
- 當遠端物件第一次作為引數或者結果傳遞時,遠端引用模組建立一個遠端物件引用,並把它新增到表中;
- 當遠端物件引用隨請求或應答訊息到達時,遠端引用模組要提供對應的本地物件引用。若遠端物件引用不在表中,則 RMI 軟體就建立一個新的代理並要求遠端引用模組將它新增到表中。
RMI 軟體
RMI 軟體由位於應用層物件和通訊模組、遠端引用模組之間的軟體層組成,涉及的中介軟體物件有如下幾種角色:
中介軟體物件 | 說明 |
---|---|
代理 | 對呼叫者表現得像呼叫本地物件一樣,從而使遠端方法呼叫對客戶透明。它不執行呼叫,而是將呼叫放在訊息裡傳遞給遠端物件。 |
分發器 | 分發器接收來自通訊模組的請求訊息,並傳遞請求訊息,並使用 methodld 選擇骨架中恰當的方法。 |
骨架 | 遠端物件類有一個骨架,用於實現遠端介面中的方法一個骨架方法將請求訊息中的引數解碼,並呼叫伺服器中的相應方法。它等待呼叫完成,然後將應答訊息傳送給傳送方代理的方法。 |
RMI 使用的代理類、分發器類和骨架類由介面編譯器自動建立,靜態的代理類是透過介面定義生成的,並且被編譯到客戶端的程式碼中。但是一個遠端引用指向了客戶端程式中的物件的不確定的遠端介面,就需要採用動態呼叫方法來呼叫該遠端物件。伺服器有時需要駐留那些介面在編譯時尚不能確定的遠端物件,使用動態骨架*的伺服器便能夠解決這種問題。
伺服器和客戶程式
伺服器程式包含分發器類和骨架類,以及它支援的所有伺服器類的實現。伺服器程式的初始化部分負責建立並初始化至少一個駐留在伺服器上的伺服器,其餘的伺服器可以應客戶發出的請求而建立。客戶程式會包含它將呼叫的所有遠端物件的代理類,它用一個繫結程式查詢遠端物件引用。客戶程式通常要使用繫結程式來獲得伺服器端至少一個遠端物件的遠端物件引用,繫結程式維護著一張表,表中包含從文字名字到遠端物件引用的對映。伺服器用該表來按名字註冊遠端物件,客戶用它來查詢這些遠端物件。
為了避免一個遠端呼叫的執行延誤另一個呼叫的執行,伺服器一般為每個遠端呼叫的執行分配一個獨立的執行緒。有些應用要求資訊能長時間地保留,但是讓該資訊物件無限期地保留在執行的程序中是不切實際的。為了避免因為在全部時間裡執行管理這些遠端物件的伺服器造成潛在的資源浪費,伺服器應該在客戶需要它們的任何時候啟動。一個遠端物件有兩種狀態:
遠端物件狀態 | 說明 |
---|---|
主動物件 | 在一個執行的程序中可供呼叫的物件 |
被動物件 | 現在不是主動的但是可以啟用為主動的,一個被動物件包括它的方法的實現、編碼格式的狀態 |
啟用是指根據相應的被動物件建立一個主動物件,具體方法是建立被動物件類的一個新例項並根據儲存的狀態初始化它的例項變數。啟用器負責註冊可以被啟用的被動物件,啟動已命名的伺服器程序並啟用程序中的遠端物件,以及跟蹤已經啟用的遠端物件所在的伺服器位置。那些在程序兩次啟用之間仍然保證存活的物件稱為持久物件,持久物件一般由持久物件儲存來管理,它在磁碟上以編碼格式儲存持久物件的狀態。當這些持久物件的方法被其他物件呼叫的時候,它們就會被啟用。啟用一般設計為透明的,呼叫者應該不能判斷一個物件是已經在主存中還是被呼叫之前已經被啟用。有兩種方法可以判斷一個物件是否是持久的:
- 持久物件儲存維護一些持久根,任何可以透過持久根訪問到的物件都被定義為持久的;
- 持久物件儲存提供一些持久類——持久物件屬於它們的子類。
有些遠端物件在其整個生命週期裡會存在於一系列不同的程序中,可能這些程序存在於不同的計算機中,此時遠端物件引用不能當做地址用。定位服務幫助客戶根據遠端物件引用定位遠端物件,它使用了一個資料庫將遠端物件引用對映到它們當前的大概位置。如果一個本地物件引用或者遠端物件引用在沒有任何物件引用它時,該物件將被收集並且它使用的記憶體將被回收。Java 的分散式無用單元收集演算法基於引用計數工作,一旦一個遠端物件引用進入一個程序,程序就會建立一個代理,只要需要這個代理它就一直存在。物件生存的程序應該告知給客戶上的新代理,隨後當客戶不再有代理也應告知伺服器。Jini 分散式系統包括一個租借規約,為了避免用複雜的協議判斷資源使用者是否還有興趣,資源只提供一段有限長的時間。提供資源的物件會負責維護它直到租期結束,資源的使用者負責在過期的時候請求延續它們的租約。
參考資料
《分散式系統概念與設計》[英]George Coulouris, Jean Dollimore, Tim Kindberg,Gordon Blair,金蓓弘,馬應龍 譯,機械工業出版社