<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    yeshucheng
    追逐自己,追逐方向,心隨悟所動(dòng)
    posts - 24,comments - 24,trackbacks - 0

     

     

    綜述

           Rmi自從JDK1.1就已經(jīng)出現(xiàn)了。而對(duì)于為什么在JAVA的世界里需要一個(gè)這樣 思想理念就需要看下:RMI問世由來。其實(shí)真正在國(guó)內(nèi)使用到它的比較少,不過在前些年比較火的EJB就是在它的基礎(chǔ)上進(jìn)一步深化的。從本質(zhì)上來講RMI的興起正是為了設(shè)計(jì)分布式的客戶、服務(wù)器結(jié)構(gòu)需求而應(yīng)運(yùn)而生的,而它的這種B/S結(jié)構(gòu)思想能否和我們通常的JAVA編程更加貼切呢?言外之意就是能否讓這種分布式的狀態(tài)做到更加透明,作為開發(fā)人員只需要按照往常一樣開發(fā)JAVA應(yīng)用程序一樣來開發(fā)分布式的結(jié)構(gòu)。那現(xiàn)在的問題是如何來劃平這個(gè)鴻溝呢?首先我們來分析下在JAVA世界里它的一些特點(diǎn)因素:

    l         JAVA使用垃圾收集確定對(duì)象的生命周期。

    l         JAVA使用異常處理來報(bào)告運(yùn)行期間的錯(cuò)誤。這里就要和我們網(wǎng)絡(luò)通訊中的異常相聯(lián)系起來了。在B/S結(jié)構(gòu)的網(wǎng)絡(luò)體系中我們的這種錯(cuò)誤性是非常常見的。

    l         JAVA編寫的對(duì)象通過調(diào)用方法來調(diào)用。由于網(wǎng)絡(luò)通訊把我們的客戶與服務(wù)器之間阻隔開了。但是代理的一種方式可以很好的提供一種這樣的假象,讓開發(fā)人員或者使用者都感覺是在本地調(diào)用。

    l         JAVA允許一種高級(jí)的使用類加載器(CLassLoader)機(jī)制提供系統(tǒng)類路徑中沒有的類。這話什么意思?

    主要特點(diǎn)

    上面說到了分布式的方式和我們的JAVA中如何更好的劃平這個(gè)鴻溝,需要具備的特質(zhì)。

    那這里我們來看看我們所謂的RMI到底跟我們普通的JAVA(或者說JavaBean)存在一些什么樣的差異:

    l         RMI遠(yuǎn)程異常(Remote Exception):在上面我們也提到了一個(gè)網(wǎng)絡(luò)通訊難免有一些無(wú)論是軟件級(jí)別的還是硬件級(jí)別的異?,F(xiàn)象,有時(shí)候這些異常或許是一種無(wú)法預(yù)知的結(jié)果。讓我們開發(fā)人緣如何來回溯這種異常信息,這個(gè)是我們開發(fā)人員要關(guān)心的。因此在調(diào)用遠(yuǎn)程對(duì)象的方法中我們必須在遠(yuǎn)程接口中(接口是一種規(guī)范的標(biāo)準(zhǔn)行為)所以在調(diào)用的這個(gè)方法體上需要簽名注明:java.rmi,RemoteException.。這也就注明了此方法是需要調(diào)用遠(yuǎn)程對(duì)象的。

    l         值傳遞 :當(dāng)把對(duì)象作為參數(shù)傳遞給一個(gè)普通的JAVA對(duì)象方法調(diào)用時(shí),只是傳遞該對(duì)象的引用。請(qǐng)注意這里談到的是對(duì)象的“引用”一詞,如果在修改該參數(shù)的時(shí)候,是直接修改原始對(duì)象。它并不是所謂的一個(gè)對(duì)象的備份或者說拷貝(說白了就是在本JVM內(nèi)存中的對(duì)象)。但是如果說使用的是RMI對(duì)象,則完全是拷貝的。這與普通對(duì)象有著鮮明的對(duì)比。也正是由于這種拷貝的資源消耗造就了下面要說到的性能缺失了。

    l         調(diào)用開銷:凡是經(jīng)過網(wǎng)絡(luò)通訊理論上來說都是一種資源的消耗。它需要通過編組與反編組方式不斷解析類對(duì)象。而且RMI本身也是一種需要返回值的一個(gè)過程定義。

    l         安全性:一談到網(wǎng)絡(luò)通訊勢(shì)必會(huì)說到如何保證安全的進(jìn)行。

     

    概念定義

    在開始進(jìn)行原理梳理之前我們需要定義清楚幾個(gè)名詞。對(duì)于這些名詞的理解影響到后的深入進(jìn)行。

    1.         Stub(存根,有些書上也翻譯成:樁基在EJB的相關(guān)書籍中尤為體現(xiàn)這個(gè)意思):

    這里舉例說明這個(gè)概念起(或許不夠恰當(dāng))。例如大家因公出差后,都有存在一些報(bào)銷的發(fā)票或者說小票。對(duì)于你當(dāng)前手頭所拿到的發(fā)票并不是一個(gè)唯一的,它同時(shí)還在你發(fā)生消費(fèi)的地點(diǎn)有一個(gè)復(fù)印件,而這個(gè)復(fù)印件就是所謂的存根。但是這個(gè)存根上并沒有很多明細(xì)的描述,只是有一個(gè)大概的金額定義。它把很多的細(xì)節(jié)費(fèi)用都忽略了。所以這個(gè)也是我們說的存根定義。而在我們RMI的存根定義就是使用了這樣一個(gè)理解:在與遠(yuǎn)程發(fā)生通訊調(diào)用時(shí),把通訊調(diào)用的所有細(xì)節(jié)都通過對(duì)象的封裝形式給隱藏在后端。這本身就符合OOAD的意思理念。而暴露出來的就是我們的接口方式,而這種接口方式又和服務(wù)器的對(duì)象具有相同的接口(這里就和我們前面舉例說的報(bào)銷單據(jù)聯(lián)系上了,報(bào)銷單據(jù)的存根不知道會(huì)有一個(gè)什么形式發(fā)生具體問題,而你手執(zhí)的發(fā)票具體就需要到貴公司去報(bào)銷費(fèi)用,而這里的公司財(cái)務(wù)處就是所謂的服務(wù)器端,它才是真正干實(shí)質(zhì)性問題的。)因此作為開發(fā)人員只需要把精力集中在業(yè)務(wù)問題的解決上,而不需要考慮復(fù)雜的分布式計(jì)算。所有這些問題都交給RMI去一一處理。

    2.         Skeleton(一些書翻譯叫骨架,也叫結(jié)構(gòu)體):它的內(nèi)部就是真正封裝了一個(gè)類的形成調(diào)用體現(xiàn)機(jī)制。包括我們熟知的ServerSocket創(chuàng)建、接受、監(jiān)聽、處理等。

    3.         Mashalling(編組):在內(nèi)存中的對(duì)象轉(zhuǎn)換成字節(jié)流,以便能夠通過網(wǎng)絡(luò)連接傳輸。

    4.         Unmashalling(反編組):在內(nèi)存中把字節(jié)流轉(zhuǎn)換成對(duì)象,以便本地化調(diào)用。

    5.         Serialization(序列化):編組中使用到的技術(shù)叫序列化。

    6.         Deserializationg(反序列化):反編組中使用到的技術(shù)叫反序列化。

     

    客戶端

           既然我們知道stub主要是以接口的方式來暴露體現(xiàn),而stub主要 也是以代理的方式來具體實(shí)施。那在RMI中的這種接口有哪些特性呢?(Remote Interface

    1)        必須擴(kuò)展(extendsjava.rmi.Remote接口,因?yàn)檫h(yuǎn)程接口并不包含任何一個(gè)方法,而是作為一個(gè)標(biāo)記出現(xiàn),它就是需要告訴JVMRunTime的時(shí)候哪些是常規(guī)對(duì)象,哪些屬于遠(yuǎn)程對(duì)象。通過這種標(biāo)識(shí)的定義能讓JVM了解類中哪些方法需要編組,通過了編組的方式才能通過網(wǎng)絡(luò)序列化的調(diào)用;

    2)        接口必須為public(公共),它的好處不言而喻的——能夠方便的讓所有人員來調(diào)用。

    3)        接口方法還需要以異常拋出(例如:RemoteException),至于它的用處我們?cè)谇懊嬉蔡岬竭@里就不再?gòu)?fù)述;

    4)        在調(diào)用一個(gè)遠(yuǎn)程對(duì)象期間(運(yùn)行期間),方法的參數(shù)和返回值都要必須是可序列化的。至于為什么需要這么做?這里的緣由不用多說大家也應(yīng)該清楚了解。

    服務(wù)端

           既然我們知道stub所做的事情是一個(gè)簡(jiǎn)單的代理轉(zhuǎn)發(fā)動(dòng)作,那我們真正要做的對(duì)象就在服務(wù)端來做了。對(duì)于使用簡(jiǎn)單的RMI我們直接去指定,但是往往一旦使用了RMI對(duì)象就存在非常多的遠(yuǎn)程方法調(diào)用,這個(gè)時(shí)候服務(wù)器端對(duì)于這么多的調(diào)用如何來判別或者說識(shí)別呢?這里就要說到的是對(duì)于RMI實(shí)現(xiàn)它會(huì)創(chuàng)建一個(gè)標(biāo)識(shí)符,以便以后的stub可以調(diào)用轉(zhuǎn)發(fā)給服務(wù)器對(duì)象使用了,而這種方式我們通常叫服務(wù)器RMI的注冊(cè)機(jī)制。言外之意就是讓服務(wù)器端的對(duì)象注冊(cè)在RMI機(jī)制中,然后可以導(dǎo)出讓今后的stub按需來調(diào)用。那它又是如何做到這種方式的呢?對(duì)于RMI來說有兩種方式可以達(dá)到這種效果:

    a)         直接使用UnicastRemoteObject的靜態(tài)方法:exportObject

    b)        繼承UnicastRemoteObject類則缺省的構(gòu)造函數(shù)exportObject。

    現(xiàn)在大家又會(huì)問他們之間又有什么區(qū)別呢?我該使用哪種方式來做呢,這不是很難做抉擇嗎?從一般應(yīng)用場(chǎng)景來說區(qū)別并不是很大,但是,這里說了“但是”哦,呵呵。大家知道繼承的方式是把父類所具備的所有特質(zhì)都可以完好無(wú)損的繼承到子類中而對(duì)于類的總老大:Object來說里面有:equals()hashCode()toString()等方法。這是個(gè)什么概念呢?意思就是說如果對(duì)于本地化的調(diào)用,他們兩個(gè)的方法(a,b)基本區(qū)別不是很大。但是我們這里強(qiáng)調(diào)的RMI如果是一種分布式的特定場(chǎng)景,具備使用哈希表這種特性就顯得尤為重要了。

    剛才說了服務(wù)端采用什么方法行為導(dǎo)出對(duì)象的。那現(xiàn)在導(dǎo)出后的對(duì)象又對(duì)應(yīng)會(huì)發(fā)生什么情況呢?

    首先被導(dǎo)出的對(duì)象被分配一個(gè)標(biāo)識(shí)符,這個(gè)標(biāo)識(shí)符被保存為:java.rmi.server.ObjID對(duì)象中并被放到一個(gè)對(duì)象列表中或者一個(gè)映射中。而這里的ID是一個(gè)關(guān)鍵字,而遠(yuǎn)程對(duì)象則是它的一個(gè)值(說到這大家有沒有覺得它原理非常像HashMap的特質(zhì)呢?沒錯(cuò),其實(shí)就是使用了它的特性),這樣它就可以很好的和前面創(chuàng)建的stub溝通。如果調(diào)用了靜態(tài)方法UnicastRemoteObject.export(Remote …),RMI就會(huì)選擇任意一個(gè)端口號(hào),但這只是第一調(diào)用發(fā)生在隨后的exportObject每次調(diào)用都把遠(yuǎn)程對(duì)象導(dǎo)出到該遠(yuǎn)程對(duì)象第一被導(dǎo)出時(shí)使用的端口號(hào)。這樣就不會(huì)產(chǎn)生混亂,會(huì)把先前一一導(dǎo)出的對(duì)象全部放入到列表中。當(dāng)然如果采用的是指定端口的,則按照對(duì)應(yīng)顯示的調(diào)用方式使用。這里稍作強(qiáng)調(diào)的是一個(gè)端口可以導(dǎo)出任意數(shù)目的對(duì)象。

    (待續(xù)……
    posted on 2009-02-02 12:04 葉澍成 閱讀(3402) 評(píng)論(3)  編輯  收藏 所屬分類: java基礎(chǔ)分布式

    FeedBack:
    # re: RMI的原理和實(shí)現(xiàn)
    2009-02-02 14:59 | ci
    good....  回復(fù)  更多評(píng)論
      
    # re: RMI的原理和實(shí)現(xiàn)
    2009-02-02 22:41 | asdfasdf
    樓主.新年快樂  回復(fù)  更多評(píng)論
      
    # re: RMI的原理和實(shí)現(xiàn)
    2010-04-27 14:26 | herrylh@163.com
    您好!向您請(qǐng)教一個(gè)rmi問題,在一個(gè)系統(tǒng)軟件里面,嵌入了一個(gè)基于rmi的遠(yuǎn)程協(xié)助模塊,當(dāng)系統(tǒng)軟件安裝在有空格的路徑里面時(shí),rmi server端 start后,客戶端(另一臺(tái)機(jī)子上)無(wú)法連接上。報(bào)出remote exception ;server端路徑?jīng)]有空格的話,另一臺(tái)機(jī)子上的客戶端可以連接。

    另外,程序是java寫的 eclipse中運(yùn)行 沒有任何錯(cuò)誤,只是打包后出現(xiàn)上一段內(nèi)容的錯(cuò)誤,感覺是路徑空格問題,但是沒找到好的解決辦法,

    如果您有時(shí)間 指教一下 不勝感激!  回復(fù)  更多評(píng)論
      
    主站蜘蛛池模板: 3344免费播放观看视频| 黄色免费网址大全| 在线观看永久免费| 亚洲精品电影天堂网| 99视频在线看观免费| 91嫩草私人成人亚洲影院| 最近中文字幕国语免费完整 | 亚洲av无码专区在线观看亚| 无码区日韩特区永久免费系列| 亚洲一区在线免费观看| 免费观看AV片在线播放| 亚洲精品天堂在线观看| 一二三四免费观看在线电影 | 亚洲精品在线免费观看| 成人免费在线看片| 亚洲日本天堂在线| 国产免费怕怕免费视频观看| 免费看黄网站在线看 | 亚洲精品无码久久久久秋霞| 免费观看美女裸体网站| 亚洲AV无码一区二区大桥未久| 四虎影在线永久免费四虎地址8848aa| 黄网站色成年片大免费高清| 久久亚洲国产成人精品无码区| 久久国产精品免费网站| 亚洲an日韩专区在线| 国产99视频免费精品是看6| 久久久精品视频免费观看 | 亚洲av午夜精品无码专区| 日本免费人成视频播放| 国产精品99爱免费视频| 亚洲国产人成在线观看69网站| 在人线av无码免费高潮喷水| 免费一区二区三区在线视频| 亚洲国产精品无码av| 4虎永免费最新永久免费地址| 久久亚洲中文无码咪咪爱| 亚洲成a人片在线观看日本| 97视频热人人精品免费| 亚欧乱色国产精品免费视频| 精品亚洲麻豆1区2区3区|