Java遠程方法調用 3

計算服務器

  開支報告的例子表示了客戶機如何從服務器得到屬性。屬性可沿兩個方向傳遞--客戶機也可將新的類型傳遞給用戶。最簡單的例子就是如圖2所示的計算服務器,該服務程序可執行任意任務,這樣整個企業內的客戶機都能利用高端或專用計算機。

rmi_white_paper_image1.gif


任務由一個簡單的本地(非遠程)接口定義:
public interface Task {
Object run();
}
運行時,它就會進行一些計算,並返回一個包含結果的對象。這完全是一般性的任務--幾乎所有計算任務都可在這個接口下實現。遠程接口ComputeServer也同樣簡單:
import java.rmi.*;
public interface ComputeServer extends Remote {
Object compute(Task task) throws RemoteException;
}
這個遠程接口的唯一目的就是使客戶機創建一個Task (任務)對象,並把它發送給服務器執行,最後返回結果。該服務器的基本實現如下:
import java.rmi.*;
import java.rmi.server.*;
public class ComputeServerImpl
extends UnicastRemoteObject
implements ComputeServer
{
public ComputeServerImpl() throws RemoteException { }
public Object compute(Task task) {
return task.run();
}
public static void main(String[] args) throws Exception {
// use the default, restrictive security manager
System.setSecurityManager(new RMISecurityManager());
ComputeServerImpl server = new ComputeServerImpl();
Naming.rebind("ComputeServer", server);
System.out.println("Ready to receive tasks");
return;
}
}


  如果您看一看compute方法就會發現,它非常簡單。它只是接受傳遞給它的對象,並返回計算的結果。main方法包括服務器的啓動代碼--它安裝了RMI的缺省安全管理程序,以防止他人存取本地系統,並創建可處理進入的請求的ComputeServerImpl對象,並將其與名字"ComputeServer"關聯。這時,服務器已經準備好接收要執行的任務,而main 也完成了其設置。
如上所述,這實際上是一種全面和實用的服務。系統可以得到改進,比如,可添加要計算的參數,從而對使用服務程序的部門進行計費。但在很多情況下,上述接口和及其實現允許使用高端計算機進行遠程計算。這又?明瞭RMI的簡單性--如果您鍵入上述類,對其進行編譯,並啓動服務程序,您就擁有了能執行任意任務的運行計算服務器。

  下面介紹一個使用這種計算服務的例子。假定您購買了一個能運行大量計算操作應用程序的非常高端的系統。管理員可在該系統上啓動一個Java虛擬機,運行ComputeServerImpl對象。該對象現在就可接受要運行的任務。

現在假定一個小組準備通過一組數據培訓一個神經網絡,以幫助制訂採購策略。他們可以採用的步驟如下:

  定義一個類--暫且稱之爲PurchaseNet。它能接受一組數據,並運行培訓數據,返回一個經過培訓的神經網絡。PurchaseNet 將實現Task (任務)接口,並在其run方法中執行其工作。他們可能還需要一個Neuron類來描述所返回的網絡中的節點,而且很可能需要其它類來描述處理過程。run方法將返回一個由一組經過培訓的Neuron對象組成的NeuralNet對象。


當這些類被編寫好並進行小規模測試時,用一個PurchaseNet 對象調用ComputeServer的compute方法。
當ComputeServerImpl對象中的RMI系統接收到作爲進入參數的 PurchaseNet對象時,它就下載PurchaseNet的實現,並調用該服務器的compute方法,並把該對象作爲Task (任務)參數。
Task,也就是PurchaseNet對象,將開始執行其執行程序。當執行程序需要諸如Neuron和NeuralNet等新的類時,它們可根據需要下載。
所有計算都將在計算服務器上執行,而客戶機線程則等待結果。(客戶機系統上的另一個線程則會顯示“正在等待”光標或使用Java的內置並行機制執行另一個任務 )。當運行返回其NeuralNet對象時,這個對象將作爲compute 方法的結果被傳遞迴客戶機。
這不需要在服務器上安裝其它軟件--所有必須完成的任務都由各部門在其自己的計算機上完成,隨後再根據需要傳遞給計算服務器主機。
這個簡單的計算服務器體系結構爲系統的分佈式功能提供了功能強大的轉換能力。一項任務的計算可以被轉移到一個能爲其提供最好支持的系統上完成。這樣的系統可以被用來:

  在ComputeServerImpl對象運行於有數據挖掘需要的主機上,支持數據挖掘應用程序。這樣可使您輕鬆地把任何計算移動到數據所在的地方。
在從當前股票價格、發貨信息或其它實時信息等外部資源獲得直接數據的服務器上運行計算任務。
通過運行ComputeServer (接受進入的請求並將其轉送到運行 ComputeServerImpl的負擔最小的服務器上)的不同實現,而將任務分佈在多個服務器上。
代理
因爲RMI允許使用Java實現下載屬性,所以您可使用RMI 編寫代理系統。代理的最簡單格式如下:

import java.rmi.*;
public interface AgentServer extends Remote {
void accept(Agent agent)
throws RemoteException, InvalidAgentException;
}
public interface Agent extends java.io.Serializable {
void run();
}
啓動一個代理也就創建了實現Agent (代理)接口、找到服務器、激活接受該代理對象的類。該代理的執行程序將被下載到服務器上運行。accept方法將啓動一個該代理的新線程,激活其run方法,然後返回,從而使該代理一直執行到run方法返回爲止。代理可通過激活在另一臺主機上運行的服務程序的accept方法而移植到該主機,而其本身則作爲將被接受的代理來傳遞,並結束其在原來主機上的線程。
面向對象的代碼重用與設計模式

  面向對象的編程是一項允許代碼重用的強大技術。很多企業組織都使用面向對象的編程來減輕創建程序的負擔和提高系統的靈活性。RMI是完全面向對象的--信息被髮送給遠程對象,而且對象可以被傳遞和返回。

Design Patterns (設計模式)目前在描述面向對象設計的實踐活動中獲得了相當大的成功。首先是因爲Design Patterns 的創新工作而使之大受歡迎,這些編程方式是一種正式描述解決某類特定問題的完整方法的途徑。所有這些設計模式都依賴於創建一個或多個抽象概念,這些抽象概念允許不同的實現,從而允許和增強軟件重用。軟件重用是面向對象技術的主要優勢,而設計模式則是促進重用的最受歡迎的技術之一。

所有設計模式都依賴面向對象的多態性--這是對象( 如Task )擁有多個實現的能力。算法的普通部分(如compute 方法)不必知道使用了哪個實現,它只需知道得到一個對象後應該對該對象採取什麼操作。特別地,計算服務器就是Command (指令)模式的一個例子,它可使您將請求 (任務)表示爲對象,並對其進行調度。

只有當包括執行程序在內的完整對象能在客戶機和服務器之間傳遞時,纔會存在這樣的多態性。DCE和DCOM等傳統的RPC系統以及CORBA等基於對象的RPC系統不能下載並執行程序,因爲它們不能把真實對象作爲參數傳遞,而只能傳遞數據。

  RMI可傳遞包括執行程序在內的所有類型,所以您可以在分佈式計算解決方案中,而不僅僅是本地計算中使用面向對象的編程--包括設計方式。如果沒有RMI這樣完全面向對象的系統,那麼您就必須放棄很多分佈式計算系統中的設計方式--以及面向對象的軟件重用的其它形式。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章