• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            聲明一下:在reprinting欄目中的文章完全是轉(zhuǎn)載,來自互聯(lián)網(wǎng),本人完全是學習之用,如果,轉(zhuǎn)載侵犯了您的版權(quán),請給我聯(lián)系一下,我會作相應處理。Email:gaoyuanxue118@gmail.com
            設計不受傳統(tǒng)網(wǎng)絡限制的 P2P 系統(tǒng)

            隨著移動計算的普及和嵌入式可聯(lián)網(wǎng)微處理器的無處不在的應用,TCP/IP 終于顯露出它已經(jīng)顯得過時。設計 Jxta 的初衷就是要突破當今基于 TCP/IP 的網(wǎng)絡的限制,從而擴展因特網(wǎng)所能觸及的范圍。在 developerWorks 的討論 Jxta 的系列的這最后一篇文章中,Sing Li 舉例說明了體現(xiàn)這種擴展的系統(tǒng),并解決了一個實際問題。您將看到 Jxta 不受客戶機/服務器網(wǎng)絡的典型約束的限制。請單擊本文頂部或底部的討論,在討論論壇與作者及其他讀者共享關于本文的心得。

            到本系列文章的 這里為止,我們仔細考察了 Jxta,一個 Java 參考實現(xiàn)的新 P2P 平臺,是如何工作的。在第一部分中,我們了解了 Jxta 的互操作特征。Jxta 被定義為一組互操作協(xié)議,可以跨硬件平臺、操作系統(tǒng)和編程語言實現(xiàn)。我們也討論了 Jxta 的操作模型和包括對等機、對等組、服務和管道在內(nèi)的許多重要概念。在第二部分中,我們的著眼點是建立和運行 Jxta。我們探討了一個 Jxta 應用程序 — Jxta shell — 并經(jīng)歷了創(chuàng)建管道并從一個對等機發(fā)送消息到另一個對等機的情形。在我們編寫 Jxta shell 擴展時,我們第一次獲得了用 Jxta API 編程的經(jīng)驗。迄今為止,我們討論 Jxta 的方式都是從下到上的。對于像我們這樣具有系統(tǒng)編程和網(wǎng)絡工程背景的人來說,這是再自然不過的。

            在本系列的這第三篇也即最后一篇文章中,我們要把事情顛倒過來。從那些從事應用級設計和體系結(jié)構(gòu)的人的角度來說,本文是自上而下看待 Jxta 的。我們從一個特定的示例問題開始,對這個問題進行分析并設計出一個解決方案,從而展示 Jxta 是如何自然地解決該問題的。

            隨著本文的進行,我們討論 Jxta 如何通過并列(juxtaposition)改變聯(lián)網(wǎng)的前景展望,我們還提供一個 Jxta 服務和客戶機的設計和代碼。

            解決一個分布式數(shù)據(jù)收集問題
            設 想一下我們需要創(chuàng)建一個大規(guī)模的氣象數(shù)據(jù)收集和分析系統(tǒng)。在這個系統(tǒng)中,我們有數(shù)百個氣象數(shù)據(jù)收集點;每個收集點配備一個微型氣象站,這些氣象站將當前溫 度(和其它大氣狀態(tài))提供給一組數(shù)據(jù)集中器。收集器遍布世界各地;這些收集器并不是都直接連接到因特網(wǎng),任何時候都可能有新的數(shù)據(jù)收集器連接上來或脫開連 接。在這個項目中,參與進來的收集器的確切數(shù)量經(jīng)常在變化;數(shù)據(jù)分析和處理基于區(qū)域平均值。

            開始時只有 10 個集中器。每個集中器監(jiān)視來自許多個收集器的數(shù)據(jù),這些數(shù)據(jù)被實時提供給關系數(shù)據(jù)庫。隨后,來自關系數(shù)據(jù)庫的數(shù)據(jù)被提供給運行氣象分析和預測的仿真模型的 超級計算機并由它處理。集中器的數(shù)量和位置會發(fā)生變化,但它們的行為則大多更穩(wěn)定。一旦安裝后,集中器就會保持運轉(zhuǎn),除非碰到系統(tǒng)失效。

            我們必須解決的問題:我們的系統(tǒng)如何能夠持續(xù)運轉(zhuǎn),并能考慮到在幾乎不影響整體性能的條件下,允許動態(tài)添加或除去收集器和集中器。

            初始分析:特定網(wǎng)絡的復雜性
            系 統(tǒng)中的某些收集器可直接訪問因特網(wǎng);其它的通過無線電傳輸技術(shù)進行連接,它們處在惡劣的外部環(huán)境中。事實上,在這些基于無線電的收集器中,許多都被設計成 了節(jié)能的,以延長電池壽命;收集器的有效范圍僅夠與下一個最近的收集器或基站聯(lián)系。這些收集器中許多都不支持 TCP/IP,而是使用基本的分組無線技術(shù)。一些更獨立的收集器僅僅靠其太陽能電池板獲得能量,并使用衛(wèi)星傳輸進行通信。還有另外一些收集器則連接到標準 蜂窩電話上,用 SMS(short message service,短消息服務)消息傳遞來發(fā)送消息。

            在項目的整個生命周期中, 可用的收集器的數(shù)量會發(fā)生變化;在項目開始時,我們無法預測將會構(gòu)建到未來收集器中的連接類型,也無法預測收集器將使用的技術(shù)。例如,在項目的某個階段, 在一個超級計算機群集內(nèi)使用軟件仿真來仿真數(shù)量巨大的收集器。我們的解決方案必須能適應所有收集器,不管是真正的還是仿真的,現(xiàn)在的還是將來的。

            解決方案:并列(Juxtaposition)
            圖 1 顯示用來解決這個問題的高層次設計。

            圖 1. 解決數(shù)據(jù)收集問題

            image請 注意,并列 P2P 網(wǎng)絡用來適應網(wǎng)絡的多種不同情況,而集中器提供 P2P 網(wǎng)絡和傳統(tǒng)的客戶機/服務器網(wǎng)絡之間的連接,數(shù)據(jù)庫服務器和超級計算機駐留在客戶機/服務器網(wǎng)絡。集中器充當兩個網(wǎng)絡之間的網(wǎng)橋 — 每個集中器在 P2P 網(wǎng)絡上具有動態(tài)特性,在客戶機/服務器網(wǎng)絡具有靜態(tài)特性。

            這個體系結(jié)構(gòu)反映了 Jxta 對傳統(tǒng)系統(tǒng)的補充作用和提供并行于這些傳統(tǒng)系統(tǒng)的增值的能力 — 通過并列(juxtaposition),Jxta 的名稱就源于這個詞語。

            我們不想深入討論這里的客戶機/服務器網(wǎng)絡的細節(jié),因為其中并沒有什么獨特之處;我們甚至可以使用 VPN 技術(shù)在因特網(wǎng)上運行它。有趣的部分在 P2P 網(wǎng)絡。圖 2 顯示了它的組成,它可隨將來的變化而變化。請注意其中用到的多種不同技術(shù)。

            圖 2. 數(shù)據(jù)收集器網(wǎng)絡的組成


            image在實現(xiàn)這個 P2P 網(wǎng)絡時,我們可以利用 Jxta,從而獲得以下優(yōu)點:

            容易地添加或除去新的收集器或集中器,這得益于 Jxta 的統(tǒng)一分散尋址


            設計簡單性,這得益于 Jxta 的網(wǎng)絡虛擬化


            持續(xù)運轉(zhuǎn),這得益于 Jxta 支持故障彈性


            免維護運轉(zhuǎn),這得益于 Jxta 支持動態(tài)自我組織網(wǎng)絡


            支持跨越許多硬件平臺和編程語言的多種不同實現(xiàn),支持所用的各種不同通信協(xié)議
            讓我們來更詳細地研究一下其中幾個益處,并看看 Jxta 如何為體系結(jié)構(gòu)的各個方面作出獨特的貢獻。

            統(tǒng)一分散尋址
            統(tǒng)一分散尋址的字面意思是,對等機可以為自己生成一個 ID 并立即加入到網(wǎng)絡,而不必與任何注冊人或中央認證機構(gòu)聯(lián)系,而當今的 DNS 則必須這樣。這一特征使我們?nèi)魏螘r候都可以向網(wǎng)絡添加收集器和集中器。

            在 本文附帶的代碼包中(您可以從參考資料下載它),我們提供了名為 mdidgen 的實用程序,它可以用來為新的 Jxta 服務和管道生成地址。(要更多了解 mdidgen,請參閱旁注 mdidgen 實用程序。)您可以閱讀本系列的第一篇文章,了解 Jxta ID 是如何用來對 Jxta 對象(例如:對等機、對等組、服務和管道)進行統(tǒng)一尋址的。

            請注意,Jxta 網(wǎng)絡中的對等機不一定要有一個獨立的物理存在。在我們的示例中,我們用一個超級計算機群集來仿真數(shù)量巨大的收集器,每個收集器有它自己的統(tǒng)一地址。這些仿 真收集器的每一個在 P2P 網(wǎng)絡的其它部分看來都是一個與那些具有物理存在的對等機沒有什么差別的對等機。

            網(wǎng)絡虛擬化
            通過分散尋址為所有收集器和集中器賦予網(wǎng)絡中唯一的標識后,它們立即就成為網(wǎng)絡中的對等機并開始彼此通信。盡管它們可能通過許多種不同的消息傳遞機制進行相互聯(lián)系,但在 Jxta 級別上,它們都只是一個虛擬網(wǎng)狀網(wǎng)絡中的節(jié)點,如圖 3 所示。

            圖 3. 網(wǎng)絡虛擬化


            image請 注意,將收集器和對等機實際相互連接起來的所有不同的傳輸和尋址模式都被虛擬化了,只留下一個網(wǎng)狀網(wǎng)絡,其中的每個對等機都與其它每一個對等機相連接。 Jxta 通過使用統(tǒng)一尋址模式和極遲綁定(very late binding),在多個端點協(xié)議上添加一個智能消息路由層做到這一點。從本質(zhì)上說,每一個端點協(xié)議或傳輸協(xié)議棧都成為虛擬 Jxta 網(wǎng)絡的一個驅(qū)動程序,將虛擬網(wǎng)絡映射到物理網(wǎng)絡上。圖 4 顯示了這種設置。

            圖 4. 端點協(xié)議作為驅(qū)動程序


            image通 信協(xié)議要成為合格的端點協(xié)議,只需要它能夠在兩個物理節(jié)點之間發(fā)送或接收 XML 消息。對傳輸可靠性或消息廣播支持沒有什么要求。因而,最簡單的分組無線協(xié)議也可以用作端點協(xié)議驅(qū)動程序,與像 TCP/IP 這樣的復雜多層協(xié)議并列。這也解釋了為什么 HTTP 和 TCP/IP 在 Jxta 協(xié)議棧內(nèi)都是同一級別的端點協(xié)議,盡管它們的物理級別非常不同。HTTP 是一個受支持的端點協(xié)議,因為只要有必要,它就能夠穿越盡可能多的防火墻,從而獲取從一個 Jxta 對等機傳送到另一個的消息。

            Jxta 網(wǎng)絡中的每個對等機可以同時支持多個端點協(xié)議,Jxta 虛擬網(wǎng)絡機制會以一種盡可能遲的方式將虛擬化的統(tǒng)一網(wǎng)絡地址映射到物理網(wǎng)絡地址(在 Jxta 中稱為網(wǎng)絡端點)。從本質(zhì)上說,一個對等機對應于一組物理端點,其中的每個物理端點可以在完全不同的物理通信協(xié)議上實現(xiàn)。較高級別的虛擬化和路由服務隱藏 了這一點。許多人或許能看出這就是多協(xié)議路由器的一個非常高級的形式 — 正是這相同的設備使當今的因特網(wǎng)成為現(xiàn)實。這一概念的發(fā)展將把我們帶向一個更加普遍的因特網(wǎng),這是再自然不過的了。

            讓我們更詳細地研究一下圖 5 所示的示例。對等機 A 是網(wǎng)絡中的一個收集器,它試圖通過一系列中介收集器(對等機 B、C 和 D)將其數(shù)據(jù)發(fā)送到集中器(對等機 E)。在圖中每個對等機的下面是該對等機所支持的一組協(xié)議。

            圖 5. Jxta 路由示例


            image因為對等機 A 不直接連接到對等機 E,所以它的消息必須通過中介對等機 B、C 和 D 進行路由。Jxta 將自動對消息進行路由:

            使用 TCP/IP 從對等機 A 到對等機 B


            使用分組無線協(xié)議從對等機 B 到對等機 C


            使用 SMS 從對等機 C 到對等機 D


            使用 HTTP 從對等機 D 到對等機 E
            對 等機 E 將在它創(chuàng)建的管道上接收來自對等機 A 的消息,完全未覺察 Jxta 為它所執(zhí)行的復雜工作。請注意,對等機 C 到對等機 D 的路徑是非對稱的;Jxta 就是專門設計來處理這種狀況的。如果有條消息要從對等機 E 發(fā)送回對等機 A,則 Jxta 將使用撥號調(diào)制解調(diào)器 PPP 自動地從對等機 D 路由到對等機 C。

            故障彈性
            盡管上面所描述的路由功能已經(jīng)令人非常驚奇,但更為重要的是, Jxta 必須能夠適合 P2P 網(wǎng)絡不斷變化的拓撲結(jié)構(gòu)。特別是它必須能夠處理充當消息路由代理的 P2P 對等機與生俱來的不可靠性。在我們的例子中,如果中繼收集器不可用,那么,依賴另一個收集器來路由它的消息的收集器將不能進行通信。

            當 有對等機加入或離開網(wǎng)絡時,Jxta 要能夠?qū)崟r對消息進行重路由。再考慮一下圖 5 中的路由示例。請設想一下,由于某些原因,就在對等機 A 已經(jīng)發(fā)送出消息(現(xiàn)在正在傳輸)而尚未到達對等機 C 時,對等機 C 和對等機 D 之間的衛(wèi)星鏈路卻斷了。Jxta 必須能夠動態(tài)地通過某些替代路徑(可能是通過另一組中間節(jié)點)將該消息重路由到對等機 E。這種動態(tài)重路由是基于最大努力(best-effort)完成的;偶而有這樣的情況,如果沒有可能的路由(除非中介傳輸支持持久隊列),則消息可能會 被丟失。由于這種重路由能夠改換實際用來到達對等機 E 的端點協(xié)議(例如:從 HTTP 到 TCP/IP),所以,要一直達到路由的最后一個跳數(shù)時,對等機到物理端點的綁定才會發(fā)生。這就是 Jxta 的極遲綁定的本質(zhì)。

            在對等組級別上(請參閱本系列的第一篇文章了解有關對等組的更多知識),Jxta 通過支持對等組服務 — 在對等組內(nèi)總是可用的、冗余地實現(xiàn)的服務 — 支持故障彈性。

            動態(tài)自我組織網(wǎng)絡
            當具有統(tǒng)一虛擬網(wǎng)絡 ID 的對等機插入到 Jxta 網(wǎng)絡中時,它必須這樣來自我引導:

            定位本地對等機并發(fā)現(xiàn)它們的功能


            發(fā)現(xiàn)可用的對等組并加入其中一個


            發(fā)現(xiàn)對等組中可用的服務并開始使用它們
            我 們從本系列的第二篇文章中了解到,這一切都是在消息級別上通過發(fā)布、中繼、中介高速緩存和搜索稱為廣告的不同類型的消息完成的。Jxta 的 Java 參考實現(xiàn)有一個解析器和使發(fā)布-高速緩存-搜索(publish-cache-search)過程簡便的集中服務層。

            Jxta 中的對等組的作用是作為網(wǎng)絡分區(qū)(network-partitioning)機制,確保廣告只被中繼到能夠使用這些廣告的組成員。不同的對等組可以包含對等機和對等組服務的不同組合,充當功能性的捆束機制。對等組也可以起到特定應用程序的認證域的作用。

            mdidgen 實用程序


            實 用類 com.ibm.jxta.mdidgen 可以用來以分散方式為 Jxta 對象生成統(tǒng)一地址。它生成一個新的 ModuleClassID、一個相應的 ModuleSpecID 和一個與某個組(在啟動時被讀取的配置文件中指定)關聯(lián)的新 PipeID。所生成的這些 ID 是立即可以使用的 Java 聲明形式,并且立即可以插入到您的代碼中。這就是我們?yōu)? ModuleSpecAdvertisement 和集中器服務管道生成 ID 的方式。

            設計 Jxta 服務和 Jxta 客戶機
            讓我們回到氣象站示例上來。從概念上說,集中器實現(xiàn)必須:

            讀取并處理適當?shù)呐渲梦募?,這個文件告訴集中器加入到哪個 Jxta 組。(樣本代碼包中包含有我們示例的配置文件。)


            啟動 Jxta。


            加入到配置文件所指定的組。


            進行搜索,以判斷集中器服務的服務廣告是否存在;如果不存在,就創(chuàng)建一個并發(fā)布它。


            創(chuàng)建一條相應于該服務的輸入管道。


            在管道等待來自收集器的消息。


            一旦消息到達,就處理它并存儲到 RDBMS 中。


            回到第 6 步。
            這個邏輯在 com.ibm.jxta.Concentrator 類中實現(xiàn)。您可以從參考資料部分下載這個類及所有來自本文的代碼。

            收集器實現(xiàn)必須:

            讀取并處理上述配置文件。


            啟動 Jxta。


            加入到配置文件所指定的組。


            發(fā)現(xiàn)集中器服務的服務廣告;如果服務廣告不可用,我們就無法繼續(xù)。


            從服務廣告抽取管道信息。


            每隔一段時間收集數(shù)據(jù)。


            創(chuàng)建包含收集器位置和數(shù)據(jù)的消息。


            通過管道將消息發(fā)送到集中器服務。


            回到第 6 步。
            上述邏輯在 com.ibm.jxta.Collector 類中實現(xiàn)。

            將公共任務分解到 DwJxtaPeer 超類
            有很多任務對收集器和集中器角色都是公共的。為了消除不必要的代碼重復并使將來的維護更簡單,讓我們把這些公共任務分解出來放入名為 com.ibm.jxta.DWJxtaPeer 的超類。

            其中一個公共任務是執(zhí)行 ModuleSpecAdvertisement 的發(fā)現(xiàn)(請參閱旁注 JXTA 中的服務廣告了解關于這個廣告的更多知識)。這由清單 1 中的 findModuleSpecAdv() 方法執(zhí)行:

            清單 1. findModuleSpecAdv()
            protected ModuleSpecAdvertisement findModuleSpecAdv() {
            return (ModuleSpecAdvertisement) findAdv("ModuleSpecAdvertisement",
            "Name",ModuleSpecName, new ModuleSpecAdvValidator(), false );
            }



            請注意,findModuleSpecAdv() 調(diào)用另一個名為 findAdv() 的通用方法,我們用這個方法發(fā)現(xiàn)廣告。findAdv() 的參數(shù)是:

            參數(shù) 描述
            AdvType 廣告類型的字符串描述 — 例如,PipeAdvertisement。
            Attr 搜索廣告時要匹配的標記 — 例如,Name。
            Value 與所指定的屬性匹配的值。
            Validator 一個實現(xiàn) FindValidate 接口的對象。這個接口有一個方法 checkAdv(),當找到一條廣告時,這個方法就被用來立即對這條廣告進行驗證。
            LocalOnly 一個布爾標志,表明該發(fā)現(xiàn)是否只應在本地執(zhí)行,還是跨網(wǎng)絡在遠程執(zhí)行。

            如清單 2 所示,該方法的第一部分通過使用組的發(fā)現(xiàn)服務的 getLocalAdvertisement() 方法,僅根據(jù)本地廣告高速緩存執(zhí)行對廣告的發(fā)現(xiàn)。請注意對 validator.checkAdv() 調(diào)用,用來對所找到的任何廣告進行驗證。

            清單 2. findAdv(),第 1 部分
            protected Advertisement findAdv(String advType, String attr, String val,
            FindValidate validator, boolean localOnly) {
            Enumeration enum = null;
            System.out.println("Looking for " + advType + ", please wait...");
            // First look in the local storage
            try {
            enum = discovery.getLocalAdvertisements(DiscoveryService.ADV,
            attr, val);

            } catch (Exception e) {
            }



            if ((enum != null) && (enum.hasMoreElements())) {
            Advertisement adv = null;
            while (enum.hasMoreElements()) {
            try {
            adv = (Advertisement) enum.nextElement();
            if( validator.checkAdv(adv))
            return adv;
            } catch(Exception e) {
            continue;
            }
            } // while
            } // if



            如果該發(fā)現(xiàn)是本地的,則邏輯就在這里停止。否則,我們就發(fā)送一條查詢到網(wǎng)絡,執(zhí)行遠程發(fā)現(xiàn)。發(fā)現(xiàn)服務將把所找到的任何廣告都存儲到本地高速緩存。我們只要給點時間就可以讓遠程發(fā)現(xiàn)發(fā)生。在清單 3 中,循環(huán)大約持續(xù)了五秒鐘:

            清單 3. findAdv(),第 2 部分
            if (localOnly)
            return null;

            System.out.println(" cannot find it locally, trying remote");
            // Now, search remote
            discovery.getRemoteAdvertisements(null, DiscoveryService.ADV,
            attr, val, 2, null);

            // Wait a bit in order to get an answer.
            int i=0;
            while (true) {
            try {
            if (i>MAXRETRIES){
            System.out.print(".");
            break;
            }
            Thread.sleep(WaitingTime);
            i++;
            } catch (Exception e) {
            }
            System.out.println("");



            此時,已發(fā)現(xiàn)的任何廣告都應可在本地高速緩存中找到。在清單 4 中,我們再次執(zhí)行一個本地檢查。

            清單 4. findadv(),第 3 部分
            // Look in the local storage again
            try {
            enum = discovery.getLocalAdvertisements(DiscoveryService.ADV,
            attr, val);

            if ((enum != null) && (enum.hasMoreElements())) {
            Advertisement adv = null;

            while (enum.hasMoreElements()) {
            try {
            adv = (Advertisement) enum.nextElement();
            if( validator.checkAdv(adv))
            return adv;
            } catch(Exception e) {
            continue;
            }
            } // while
            }
            } catch (Exception e) {
            }
            }
            return null;
            }



            超類中的另兩個公共方法的描述在下表中;您可以作為練習完成對它們的分析。

            方法 描述
            PublishModuleSpecAdv() 如果發(fā)現(xiàn)過程沒有為服務找到現(xiàn)有的 ModuleSpecAdvertsiement,則這個方法被集中器調(diào)用。這個方法將創(chuàng)建一個服務(根據(jù)我們所生成的、固定的服務 ID)。這條廣告將在本地和遠程發(fā)布。僅在集中器第一次啟動時,當配置改變時,或者在本地高速緩存被清除后,才有創(chuàng)建廣告的必要。
            JoinGroupIfExists() 這個方法為收集器和集中器所調(diào)用;它嘗試加入到一個已命名的子組(subgroup),這個子組是全局 NetPeerGroup(缺省情況下大家都在這個組)的子(child)組。

            請看一下清單 5,它是 DwJxtaPeer 類的常數(shù)聲明部分的一部分:

            清單 5. 模塊 ID 定義
            public static final String ClassID =
            "urn:jxta:uuid-EE99266A1DE84E3DB34D9CC842EC889105";
            public static final String SpecID =
            "urn:jxta:uuid-EE99266A1DE84E3DB34D9CC842EC8891B9EB13ECA6FE44DDA112B5F5E357763006";


            Jxta 中的服務廣告


            服務廣告概念分解成一組相互聯(lián)系的廣告(共三條):
            ModuleClassAdvertiseent
            ModuleSpecAdvertisement
            MdouleImplAdvertisement

            為了減小在系統(tǒng)中循環(huán)的廣告的大小,也為了將服務的通用類(例如:銀行)、該類的特定規(guī)范(例如:存款和提款 API)和該服務(例如:API 基于 Java 的實現(xiàn))的實現(xiàn)之間的關系規(guī)格化,這樣做都是必要的。

            應用程序或 Jxta 服務不必使用所有這些廣告,只要使用它所需要的就行了。在我們的系統(tǒng)中,我們只需要ModuleSpecAdvertisement,我們用它將服務連到管道上,并使這條廣告是遠程可發(fā)現(xiàn)的。

            ModuleClassID 和 ModuleSpecID 用 mdidgen 實用程序生成并以硬編碼方式置于模塊中;它們與一個集中器服務的 ID 相對應。所有的集中器都知道這個服務的 ID,而且這個 ID 一旦生成就一直保持不變,所以組中的收集器肯定能夠找到這個集中器服務。因為生成 ModuleSpecID 時需要 ModuleClassID,所以這里有 ModuleClassID。為了輕松生成這些 ID,我們使用一個名為 AdvCooker 的庫,它是 W.R. Bauer(vasha@jxta.org)創(chuàng)建的名為 jxta-wire 的 Jxta 項目的一部分。

            網(wǎng)絡中運行的所有集中器實例將對同一個集中器對等組服務(通過使用相同的 ModuleSpecID 和偵聽廣播管道的同一個邏輯實例)作出應答。這種冗余實現(xiàn)將確保集中器服務在對等組中始終可用。

            集中器:一個 Jxta 對等組服務
            我們來看一下 com.ibm.jxta.Concentrator 實現(xiàn)。我們已經(jīng)提到過,它繼承(擴展)自 DwJxtaPeer 類。這里是逐個方法地對 Concentrator 進行的描述:

            方法 描述
            init() 它應該是該類被調(diào)用的第一個方法。這個方法調(diào)用私有 jxtaInit() 方法,然后創(chuàng)建輸入集中器服務管道的一個實例。
            process() 這個方法進入一個無限循環(huán)。它在輸入集中器服務管道上偵聽傳入的收集器數(shù)據(jù)提交。對每一個提交,它都調(diào)用 processData() 對數(shù)據(jù)進行處理。
            findPipeAdv() 這個方法對服務管道廣告執(zhí)行本地發(fā)現(xiàn)(也就是說,它檢查本地高速緩存)。
            jxtaInit() 這個方法首先讀取配置文件并設定我們想要加入到的組。接著,它啟動 Jxta 和 NetPeerGroup 網(wǎng)絡,然后調(diào)用超類的 joinGroupIfExist() 加入到指定的組。接著,如果能夠,它就從本地高速緩存檢索服務管道廣告;否則,它將創(chuàng)建一個新的服務管道廣告(通過使用 createInputPipeAdvIfNotExist())。最后,它執(zhí)行發(fā)現(xiàn),看看是否可以找到 ModuleSpecAdvertisement;如果不能找到,它就創(chuàng)建一個并發(fā)布它。
            processData() 這個方法是占位符。在實際的項目中,它將使用后端客戶機/服務器網(wǎng)絡將所收集到的數(shù)據(jù)提交給 RDBMS(可能使用 JDBC)。
            createInputPipeAdvIfNotExist() 這個助手方法首先檢查高速緩存,看看服務管道廣告是否可用。如果不可用,它將創(chuàng)建該廣告并將它存儲到高速緩存中。在任一種情況下都返回正確的廣告。

            靜態(tài)類型定義如下:


            public static String servicePipeID =
            "urn:jxta:uuid-969610EE8945417CA56F9771197EE3965207E4C303154E7EB5878751AE22761804";




            這 是由 mdidgen 實用程序生成的管道 ID。它是該服務管道的統(tǒng)一地址,被所有集中器使用。它是一條廣播管道,因而偵聽消息的所有集中器都應接收到那些來自收集器的消息。收集器從作為 ModuleSpecAdvertisement 的一部分的管道廣告中獲得這個管道 ID;收集器通過發(fā)現(xiàn)過程找到該廣告。

            收集器:編寫 Jxta 客戶機邏輯的代碼
            最后,我們來看一下 com.ibm.jxta.Collector 類的本地方法。

            方法 描述
            init() 它應該是從這個類中調(diào)用的第一個方法。這個方法調(diào)用私有 jxtaInit(),然后創(chuàng)建用來將所收集到的數(shù)據(jù)發(fā)送到集中器服務的輸出管道。
            process() 這個方法有一個無限循環(huán),這個循環(huán)首先調(diào)用 collectData() 獲得測量的數(shù)據(jù),接著,創(chuàng)建一條 Jxta 消息并沿集中器服務管道將它發(fā)送到正在等待的集中器。循環(huán)內(nèi)每次采樣都延遲一段固定時間。
            jxtaInit() 這個方法首先讀取配置文件并對我們想要加入到的組進行設置,接著確定收集器的位置。接著,它啟動 Jxta 和 NetPeerGroup 網(wǎng)絡,然后調(diào)用超類的 joinGroupIfExist() 加入到指定的組。接著,它執(zhí)行發(fā)現(xiàn),看看是否可以找到相應于眾所周知的集中器服務的 ModuleSpecAdvertisement;如果找不到,則退出。一旦找到了 ModuleSpecAdvertisment,它就將抽取集中器服務管道廣告并為輸出管道的創(chuàng)建做好準備。
            collectData() 這個方法是一個占位符,用于實際的數(shù)據(jù)收集。在實際的項目中,這個方法將訪問各種數(shù)據(jù)輸入通道(可能使用輸入/輸出端口或本機代碼)并將所收集到的數(shù)據(jù)返回給調(diào)用者。

            實際運轉(zhuǎn) Jxta:在您自己的機器上測試這個動態(tài)網(wǎng)絡
            本文附帶的源代碼包中有一個便于您實驗的目錄結(jié)構(gòu)。下面的目錄在 code 子目錄下:

            目錄 描述
            lib 來自 Jxta 核心最新穩(wěn)定版的所有 jar 文件,用于 Jxta shell 的所有 jar 文件以及來自 jxta-wire 項目的 jxta-wire.jar 文件都放在這里。(請參閱參考資料了解關于 Jxta shell 和 jxta-wire 的更多信息。)
            src 包含我們系統(tǒng)的源代碼。
            classes 包含我們系統(tǒng)的編譯好的類文件。
            shell1 第一個實驗目錄。我們將在這個目錄創(chuàng)建一個帶有一個集中器的 shell。我們還將在這里充分考查 mdidgen 實用程序。
            shell2 設置為網(wǎng)絡中的第二個對等機。這將運行另一個集中器。
            shell3 設置為網(wǎng)絡中的第三個對等機。這將運行一個收集器。

            要編譯這些代碼,您需要安裝 JDK 1.3 或更新版本。在 code 目錄時,執(zhí)行 MAKEIT.BAT 批處理文件。這將編譯代碼并在 classes 目錄中創(chuàng)建類文件。

            接著,運行 MAKEJAR.BAT 批處理文件。這將創(chuàng)建一個包含所有代碼的 dwjxta.jar 文件;將它放到 lib 目錄,為實驗做好準備。

            現(xiàn)在,請啟動三個不同的命令窗口。將它們的目錄分別改到 shell1、shell2 和 shell3。

            在 shell1 目錄中編輯 runshell.bat 文件,將您在配置期間用來設置安全性的用戶標識和密碼反映出來(密碼必須至少八個字符長)。編輯 runconc.bat 和 mdidgen.bat 文件,同樣要有這個用戶標識和密碼。

            使用 runshell.bat 運行這個 shell,并按以下所示配置這個對等機:

            對等機名: node1
            傳輸: TCP/IP 啟用,HTTP 禁用,選中作為集中點,無中繼
            所用 TCP 端口: 9701
            安全性用戶名和密碼: 如在批處理文件中所定制

            因為我們的系統(tǒng)假設已經(jīng)創(chuàng)建了一個用于操作的組,所以我們需要在該 shell 中創(chuàng)建這個組。在這個 shell 中時,使用以下命令創(chuàng)建 dwtest 組:


            Jxta> myadv = mkadv -g dwtest
            Jxta> mygrp = mkpgrp -d myadv dwtest



            這將創(chuàng)建我們將使用的 dwtest 組。您可以這樣來確認它已經(jīng)被創(chuàng)建:


            Jxta>groups
            group0: name = dwtest



            現(xiàn)在您可以退出該 shell。

            現(xiàn)在,請使用 mdidgen.bat 文件試驗統(tǒng)一地址(ID)的分散生成。當您運行這個文件時,應得到類似這樣的輸出:

            清單 6. mdidgen.bat 的輸出
            remote group discovery message sent
            group joined successfully
            public static final String ClassID =
            "urn:jxta:uuid-DCDD418FCC194040AA13A52A334B967105";
            public static final String SpecID =
            "urn:jxta:uuid-DCDD418FCC194040AA13A52A334B96716C515B975C2941AD9FBC90178B6918A806";
            public static final String PipeID =
            "urn:jxta:uuid-2184CACA259B42E0A866AEA788A923054C519D304E07415195B0917C81238FD004";



            請注意所生成的 ModuleClassID、ModuleSpecID 和 PipeID。這就是我們獲得在集中器服務用到的 ID 的辦法。

            通過執(zhí)行 runconc.bat 文件啟動集中器。這將讀取 dwConfig 文件,這個文件告訴集中器加入到 dwtest 組。您的輸出應與此有些相似:

            清單 7. 1 號集中器(runconc.bat)的輸出
            Starting Jxta...
            Joining default NetPeerGroup...
            Attempting to join group: dwtest
            remote group discovery message sent
            group joined successfully
            group dwtest joined successfully
            Look for previously created Pipe Adv, create one if not exist
            Looking for PipeAdvertisement, please wait...
            Previously published pipe advertisement not found, creating a new one.
            Locally caching the new pipe advertisement...
            Checking to see if MSA previously published...
            Looking for ModuleSpecAdvertisement, please wait...
            cannot find it locally, trying remote
            ... MSA not found, need to create it
            Creating new MSA
            Locally and remotely publish the MSA
            Creating pipe for data collection...
            pipe created successfully
            Waiting for data from collector...



            到這里,集中器實例就建立好了,并且為接收來自收集器的數(shù)據(jù)做好了準備。

            現(xiàn)在,到 shell2 命令窗口中編輯 runconc.bat 文件,將您的安全性用戶標識和密碼反映出來。接著,使用 runconc.bat 文件運行集中器實例。在配置過程中設置以下參數(shù):

            對等機名: node2
            傳輸: TCP/IP 啟用,HTTP 禁用,無集中點,無中繼
            所用 TCP 端口: 9702
            安全性用戶名和密碼: 如在批處理文件中所定制

            如果一切都正確運行,則您應看到與此相似的輸出:

            清單 8. 2 號集中器(來自 Shell2 的 runconc.bat 輸出)
            Starting Jxta...
            Joining default NetPeerGroup...
            Attempting to join group: dwtest
            remote group discovery message sent
            group joined successfully
            group dwtest joined successfully
            Look for previously created Pipe Adv, create one if not exist
            Looking for PipeAdvertisement, please wait...
            Checking to see if MSA previously published...
            Looking for ModuleSpecAdvertisement, please wait...
            .. found previously published MSA
            Creating pipe for data collection...
            pipe created successfully
            Waiting for data from collector...



            請注意,集中器的 ModuleSpecAdvertisement 被找到了,所以這個集中器實例不必另外創(chuàng)建一個 ModuleSpecAdvertisement?,F(xiàn)在它也在等待來自收集器的輸入。

            最 后,到 shell3 命令窗口中編輯 runcoll.bat 文件,將您的安全性用戶標識和密碼反映出來。接著,使用 runcoll.bat 文件運行收集器實例。這個實例將使用 shell3 目錄中的 dwColConfig 文件,該文件告訴收集器應加入到 dwtest 組,這個組的位置是“Timbuktu North”。在配置過程中設置以下參數(shù):

            對等機名: node3
            傳輸: TCP/IP 啟用,HTTP 禁用,無集中點,無中繼
            所用 TCP 端口: 9703
            安全性用戶名和密碼: 如在批處理文件中所定制

            這個收集器實例將開始查找 ModuleSpecAdvertisement 并且應該能找到。然后,它將創(chuàng)建一條管道與已經(jīng)運行的集中器通信。您應看到與此相似的輸出:

            清單 9. 收集器(來自 Shell3 的 runcoll.bat 的輸出)
            Reading config file, dwColConfig, and processing...
            group to join will be dwtest
            collector location is Timbuktu North
            Starting Jxta...
            Joining default NetPeerGroup...
            Attempting to join group: dwtest
            remote group discovery message sent
            group joined successfully
            group dwtest joined successfully
            Searching for collector's MSA...
            Looking for ModuleSpecAdvertisement, please wait...
            cannot find it locally, trying remote
            .. found collector's MSA
            Extracting pipe adv from MSA...
            Connecting to concentrator network...
            pipe created successfully
            ... collecting data....
            ... data collected, sending to concentrator
            waiting until next sample...
            ... collecting data....
            ... data collected, sending to concentrator
            waiting until next sample...



            請注意,數(shù)據(jù)被收集起來并定期發(fā)送到集中器服務。當數(shù)據(jù)穿過 P2P 網(wǎng)絡以及兩個集中器接收這些數(shù)據(jù)并進行處理時,請注意觀察。

            高難度的應用模式
            我 們的氣象收集示例說明了這樣一個應用模式:在一般的方面,它使用普遍流行的應用 P2P 系統(tǒng);從特定的方面,它使用 Jxta。這個模式包含兩個耦合極其松散的群體:消費者和生產(chǎn)者。當消費者想要生產(chǎn)者所生產(chǎn)的產(chǎn)品時,消費者不愿作出堅定的許諾,也不愿受限于特定生產(chǎn) 者。在這種想法背后可能有幾個現(xiàn)實動機。消費者可能想:

            可以在任意時間進行選擇,以選擇最佳的可用生產(chǎn)者


            降低對某個生產(chǎn)者的成功或失敗的依賴風險


            從非常龐大的動態(tài)社區(qū)中選擇,這種社區(qū)的大小和拓撲結(jié)構(gòu)在物理上是難于管理的
            當 消費者群體和生產(chǎn)者群體出現(xiàn)交迭時,這種模式變得十分有趣,當前可用的、流行的、世界范圍內(nèi)的文件共享系統(tǒng)就例證了這一點。與傳統(tǒng)的聯(lián)網(wǎng)技術(shù)不同,P2P 系統(tǒng)從一開始就是設計來適應這種應用模式的。特別地,與使用傳統(tǒng)的客戶機/服務器技術(shù)進行設計時,必須提供的復雜的解決方案不同,Jxta 使得創(chuàng)建這些系統(tǒng)既容易又輕松。

            超越 TCP/IP 的聯(lián)網(wǎng)
            為了真正突出 Jxta 帶來的價值,我選擇了全球氣象信息收集系統(tǒng)作為一個示例。然而,這個問題及解決方案具有許多業(yè)務模式(business scenario)的典型特征,這些業(yè)務情形如移動銷售隊伍自動化、商品貿(mào)易、內(nèi)容分發(fā)和企業(yè)到企業(yè)電子商務等等,可以列出很多。您可以同時使用 P2P 網(wǎng)絡和傳統(tǒng)的客戶機/服務器網(wǎng)絡,從而構(gòu)建大大超出當今靜態(tài)邊界的新型網(wǎng)絡解決方案。開放源代碼的 Jxta 平臺將是這些新型解決方案的實現(xiàn)工具。我希望本系列已經(jīng)激起您探索 Jxta 提供的可能性的愿望。

            from-ibm developer

            posts - 4, comments - 8, trackbacks - 0, articles - 2

            Copyright © heart in the world

            亚洲精品美女久久久久99小说| 久久久久久亚洲精品不卡| 久久久黄色大片| 中文字幕热久久久久久久| 99久久免费国产精品热| 久久精品亚洲欧美日韩久久| 久久久久久午夜精品| 青青草原综合久久大伊人精品| 久久久久久亚洲精品不卡| 久久婷婷五月综合97色| 婷婷久久综合九色综合九七| 99久久99这里只有免费费精品| 久久久久久久国产免费看| 久久天天躁狠狠躁夜夜avapp| 蜜臀久久99精品久久久久久| 久久精品国产亚洲AV香蕉| 久久国产成人午夜AV影院| 久久夜色精品国产噜噜噜亚洲AV | 无码任你躁久久久久久老妇| www久久久天天com| 国产成人久久精品一区二区三区| 热久久这里只有精品| 精品999久久久久久中文字幕| 久久国语露脸国产精品电影| 日本亚洲色大成网站WWW久久 | 色综合久久久久综合99| 久久久久综合国产欧美一区二区| 国产成人综合久久综合| 久久这里只有精品18| 色婷婷久久综合中文久久蜜桃av | 91亚洲国产成人久久精品网址 | 久久久久久毛片免费看| 国产精品日韩欧美久久综合| 久久九九青青国产精品| 99久久免费国产特黄| 国产精品久久久久久搜索| 99久久99久久| 久久免费视频观看| 久久性精品| 77777亚洲午夜久久多喷| 18禁黄久久久AAA片|