国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

Java RMI分布式系統(tǒng)應(yīng)用研究

2014-02-25 04:31:09陳小芳
電腦知識與技術(shù) 2014年1期
關(guān)鍵詞:分布式

摘要:RMI是開發(fā)Java網(wǎng)絡(luò)分布式應(yīng)用系統(tǒng)的一個重要框架,開發(fā)人員通過運用RMI框架將更易于分布式系統(tǒng)的開發(fā)。該文詳細(xì)介紹了RMI的運行機制,并對運用RMI框架進(jìn)行分布式系統(tǒng)的開發(fā)步驟進(jìn)行了闡述,最后給出了RMI技術(shù)的具體應(yīng)用實例和實現(xiàn)方法。

關(guān)鍵詞:RMI;Java;Stub;分布式

中圖分類號:TP393 文獻(xiàn)標(biāo)識碼:A 文章編號:1009-3044(2014)01-0051-03

1 概述

由于單臺計算機的計算能力有限,在實際的應(yīng)用中,我們常常要將計算任務(wù)分成多個子任務(wù),將每個子任務(wù)放到網(wǎng)絡(luò)中不同的計算機上進(jìn)行計算,實現(xiàn)分布式并行計算,以加快計算速度。在分布式計算模型中不管采取何種方式,主要是將分部在不同計算機上的對象間發(fā)送的消息轉(zhuǎn)換為字節(jié)序列,然后通過套接字建立連接并傳輸這些字節(jié)序列。在網(wǎng)絡(luò)連接和傳輸消息時還要考慮出現(xiàn)的各種故障和安全問題以及對象垃圾收集機制等等問題。

在具體的分布式系統(tǒng)實現(xiàn)過程中,一種是采用基于消息方式實現(xiàn)各個節(jié)點間的通信。當(dāng)系統(tǒng)要通信時就向外發(fā)送消息,消息可以是字節(jié)流、字節(jié)數(shù)組,其他系統(tǒng)接收到消息后則進(jìn)行相應(yīng)的業(yè)務(wù)處理。這種系統(tǒng)間通信的方式,通?;诰W(wǎng)絡(luò)協(xié)議來實現(xiàn),常用的實現(xiàn)系統(tǒng)間通信的協(xié)議有:TCP/IP和UDP/IP。另一種是采用基于遠(yuǎn)程調(diào)用方式實現(xiàn)系統(tǒng)間的通信。這種方式當(dāng)系統(tǒng)間要通信時,可通過調(diào)用本地的一個Java接口的方法,透明地調(diào)用遠(yuǎn)程的Java實現(xiàn)。具體的細(xì)節(jié)則由Java或框架來完成,盡可能地使系統(tǒng)間的通信和系統(tǒng)內(nèi)一樣,讓使用者感覺調(diào)用遠(yuǎn)程方法同調(diào)用本地方法一樣。

因為開發(fā)一個完善的分布式軟件系統(tǒng)相當(dāng)復(fù)雜,如果采用基于消息的方式實現(xiàn)分布式通信,相當(dāng)麻煩。開發(fā)人員不僅僅要關(guān)注對數(shù)據(jù)的業(yè)務(wù)處理,還要關(guān)注很多純技術(shù)細(xì)節(jié)。而基于遠(yuǎn)程調(diào)用方式實現(xiàn)分布式通信的方法解放了開發(fā)人員的一些純技術(shù)細(xì)節(jié)問題,使開發(fā)人員能夠更專注于業(yè)務(wù)數(shù)據(jù)的處理。Java為我們開發(fā)分布式網(wǎng)絡(luò)應(yīng)用提供了比較完善的遠(yuǎn)程方法框架,那就是Java RMI(Remote Method Invocation,遠(yuǎn)程方法調(diào)用)。通過RMI,可以很方便地讓Java程序調(diào)用網(wǎng)絡(luò)中其他計算機上的Java方法。

2 RMI系統(tǒng)運行機制

RMI是Java用于實現(xiàn)透明遠(yuǎn)程調(diào)用的重要機制。在遠(yuǎn)程調(diào)用中,客戶端僅有服務(wù)器端提供的接口??蛻舳送ㄟ^此接口實現(xiàn)對遠(yuǎn)程服務(wù)器端的方法調(diào)用。

RMI服務(wù)器端通過啟動RMIRegistry (RMIRegistry是運行在服務(wù)器上的一個后臺進(jìn)程,且必須在服務(wù)進(jìn)程啟動之前啟動)在一個端口上監(jiān)聽對外提供的接口,其實現(xiàn)實例以字符串的方式綁定到RMI注冊對象上。RMI客戶端程序采用命名服務(wù)機制通過注冊表獲取遠(yuǎn)程對象的存根stub。當(dāng)要調(diào)用遠(yuǎn)程方法時,通過此stub將被訪問的遠(yuǎn)程對象的名字、被調(diào)用的方法描述和相關(guān)的參數(shù)封裝成一個對象,序列化成流后傳輸?shù)絉MI服務(wù)器端。RMI服務(wù)器端skeleton接收到客戶端的請求對象后,解析其中的對象字符串、方法和參數(shù),通過對象字符串和訪問的方法名稱來反射獲取到方法實例對象,傳入?yún)?shù)完成對服務(wù)器端對象實例的調(diào)用。然后獲得方法調(diào)用產(chǎn)生的返回值或者異常,并對其進(jìn)行序列化然后返回給客戶端??蛻舳说膕tub接收到服務(wù)器端skeleton發(fā)送過來的返回值或者異常的序列化字節(jié)流后,對其進(jìn)行反序列化,就得到調(diào)用遠(yuǎn)程方法的返回結(jié)果。RMI的具體運行機制如圖1。

圖1 RMI運行機制

3 RMI技術(shù)應(yīng)用實例開發(fā)步驟

3.1 創(chuàng)建遠(yuǎn)程接口

RMI中要求遠(yuǎn)程對象所屬的類實現(xiàn)一個遠(yuǎn)程接口,遠(yuǎn)程對象必須通過遠(yuǎn)程接口聲明服務(wù)。在遠(yuǎn)程接口中聲明可以被客戶程序訪問的遠(yuǎn)程方法。此接口必須要直接或間接繼承java.rmi.Remote接口。由于遠(yuǎn)程方法調(diào)用依賴于網(wǎng)絡(luò)通信,而網(wǎng)絡(luò)通信是不可靠的,一旦服務(wù)器端或客戶端有一方斷開連接,或者網(wǎng)絡(luò)出現(xiàn)故障,此次通信就會失敗。所以在接口中的所有方法需要聲明拋出java.rmi.RemoteException異常。當(dāng)遠(yuǎn)程方法調(diào)用出現(xiàn)網(wǎng)絡(luò)通信異常時,RMI框架拋出RemoteException異常,客戶端捕獲這種異常,并進(jìn)行相應(yīng)的處理。

實例代碼如下:

import java.rmi.*;

public interface Account extends Remote{

public int add(int i,int j) throws RemoteException;

}

3.2 實現(xiàn)遠(yuǎn)程接口

遠(yuǎn)程接口中定義的遠(yuǎn)程方法的具體實現(xiàn)都在遠(yuǎn)程接口的實現(xiàn)類中,遠(yuǎn)程接口的實現(xiàn)類中也可以定義一些本地方法,這些本地方法不需要在遠(yuǎn)程接口中聲明,也無需拋出RemoteException異常,本地方法只能被本地調(diào)用,不能被遠(yuǎn)程調(diào)用。遠(yuǎn)程接口的實現(xiàn)類需要繼承java.rmi.server.UnicastRemoteObject類。因為RMI框架中關(guān)于遠(yuǎn)程對象的生命周期、基于TCP的連接傳輸、客戶端和服務(wù)器端的遠(yuǎn)程對象、方法、參數(shù)序列化后的流協(xié)議交流功能在UnicastRemoteObject類中實現(xiàn)。所以遠(yuǎn)程接口的實現(xiàn)類必須直接或間接繼承UnicastRemoteObject類。

實例代碼如下:

import java.rmi.*;

import java.rmi.server.UnicastRemoteObject;

public class AccountImpl extends UnicastRemoteObject implements Account{

public AccountImpl() throws RemoteException {

super();

}

public int add (int i,int j) throws RemoteException{ //遠(yuǎn)程方法

System.out.println("調(diào)用add()方法");

int result = i + j;

System.out.println("Server:3 + 5 = " + result);

return result;

}}

3.3 創(chuàng)建服務(wù)器端

服務(wù)器端首先要創(chuàng)建遠(yuǎn)程對象實例,然后向rmiregistry注冊表注冊此遠(yuǎn)程對象實例,把遠(yuǎn)程對象實例與一個名字綁定。rmiregistry注冊表的相關(guān)功能由JDK的安裝目錄里的一個提供命名服務(wù)的注冊表程序rmiregistry.exe完成。

實例代碼如下:

import java.net.*;

import java.rmi.*;

import java.rmi.registry.LocateRegistry;

public class RMIServer {

private static final int PORT = 10002;

private static final String HOST_NAME = "localhost";

public RMIServer() throws RemoteException, MalformedURLException,NotBoundException {

//啟動RMI注冊表線程,并將RMI服務(wù)器綁定在PORT端口上

LocateRegistry.createRegistry(PORT);

System.out.println("Registry created on host computer " + HOST_NAME +

" on port " + Integer.toString(PORT));

Account ac = new AccountImpl(); //實例化遠(yuǎn)程對象

System.out.println("Remote AccountService implementation object created");

String urlString = "http://" + HOST_NAME + ":" + PORT + "/" + "AccountService";

Naming.rebind(urlString, ac); //將遠(yuǎn)程對象的名字綁定到遠(yuǎn)程對象的引用上

System.out.println("Bindings Finished, waiting for client requests.");

}

public static void main(String[] args) {

System.setSecurityManager(new RMISecurityManager());

try {

RMIServer rmi = new RMIServer();

}catch(Exception e){

e.printStackTrace();

}} }

3.4 創(chuàng)建客戶端

客戶端程序首先需要獲得遠(yuǎn)程對象的存根對象,然后通過此存根對象來調(diào)用方法。這些存根由rmic生成。

實例代碼如下:

import java.rmi.*;

import java.rmi.server.*;

import java.rmi.registry.LocateRegistry;

public class RMIClient {

private static final int PORT = 10002;

private static final String HOST_NAME = "localhost";

public RMIClient() {

try {

Account ac = (Account) Naming.lookup("rmi://" + HOST_NAME + ":" + PORT + "/AccountService"); //通過遠(yuǎn)程對象名字查找遠(yuǎn)程對象,并返回遠(yuǎn)程接口的引用

System.out.println("AccountService lookup successful");

int result = ac.add(3,5); //調(diào)用遠(yuǎn)程對象的方法

System.out.println("Client:3 + 5 = " + result);

} catch (Exception e){

e.printStackTrace();

} }

public static void main(String[] args) {

RMIClient rmi = new RMIClient();

} }

4 編譯與運行RMI系統(tǒng)步驟

對程序的具體執(zhí)行步驟需要先編譯然后執(zhí)行注冊程序、服務(wù)器端程序和客戶端程序,在具體的執(zhí)行過程中需要將JDK的安全策略文件java.policy中的java.net.SocketPermission賦予listen,connect,accept權(quán)限。具體編譯與運行RMI系統(tǒng)步驟如下:

1) 使用javac編譯遠(yuǎn)程接口類、遠(yuǎn)程接口實現(xiàn)類、服務(wù)端和客戶端類文件。

運行cmd命令打開控制臺,在控制臺窗口執(zhí)行

c:\rmi>javac *.java

2) 使用rmic編譯器生成實現(xiàn)類的Stub和Skeleton,注意在新版的RMI機制下,只生成Stub文件,Skeleton文件不會生成。

c:\rmi>rmic AccountImpl

3) 運行rmiregistry命令,啟動RMI注冊監(jiān)聽進(jìn)程。

c:\rmi>start rmiregistry (下轉(zhuǎn)第66頁)

(上接第53頁)

4) 運行服務(wù)器端類,注冊RMI對象,服務(wù)器端準(zhǔn)備就緒,等待遠(yuǎn)程客戶端的調(diào)用。

c:\rmi>start java RMIServer

5) 啟動客戶端

c:\rmi>java RMIClient

5 結(jié)束語

通過以上分析可知Java RMI的結(jié)構(gòu)非常清楚,程序員可以利用此框架非常方便、快速的進(jìn)行分布式程序的編寫,而不需要對底層的一些通信細(xì)節(jié)進(jìn)行考慮,大大提高了程序員編寫代碼的效率。而且由于Java自身的純面向?qū)ο筇匦?,其實現(xiàn)非常方便且透明,為使用分布式對象技術(shù)提供了一個可靠的平臺。

參考文獻(xiàn):

[1] Robert Orfali,Dan Harkey.Java與CORBA客戶/服務(wù)器編程[M].2版.北京:電子工業(yè)出版社,2004.

[2] 林昊.分布式Java應(yīng)用基礎(chǔ)與實踐[M].北京:電子工業(yè)出版社,2010.

[3] 孫衛(wèi)琴.Java網(wǎng)絡(luò)編程精解[M].北京:電子工業(yè)出版社,2009.

[4] 孟憲福.分布式對象技術(shù)及其應(yīng)用[M].北京:清華大學(xué)出版社,2008.

[5] 劉丹,程曉,侯德林.一種基于RMI的分布式架構(gòu)設(shè)計[J].計算機應(yīng)用與軟件,2007(9):206-208.

猜你喜歡
分布式
分布式光伏發(fā)展的四大矛盾
能源(2017年7期)2018-01-19 05:05:03
分布式光伏熱錢洶涌
能源(2017年10期)2017-12-20 05:54:07
基于預(yù)處理MUSIC算法的分布式陣列DOA估計
分布式光伏:爆發(fā)還是徘徊
能源(2017年5期)2017-07-06 09:25:54
西門子 分布式I/O Simatic ET 200AL
家庭分布式儲能的發(fā)展前景
汽車電器(2014年5期)2014-02-28 12:14:10
安吉县| 平塘县| 当涂县| 信阳市| 漳州市| 鄂伦春自治旗| 奉新县| 关岭| 利川市| 开江县| 和静县| 达拉特旗| 齐河县| 镇安县| 五常市| 长垣县| 武汉市| 合山市| 张掖市| 新竹市| 昌黎县| 新平| 资中县| 叙永县| 黎川县| 循化| 永寿县| 定州市| 天柱县| 亳州市| 徐水县| 峨眉山市| 康定县| 凤阳县| 洱源县| 邢台县| 洮南市| 霞浦县| 德保县| 西华县| 信阳市|