前言
在上一期中,我們說明了是因為什麼樣的因緣際會,導致目前的分散式運算環境,同時也因為軟硬體的演進潮流,引領了目前的網路發展方向。在本期中,我們將詳細說明Jini系統的運作,包括每個系統中的成員要如何告知自己的存在,以及如何去尋找到適當的服務等等,且聽筆者娓娓道來。
Jini系統概觀
在本文中,筆者將對Jini系統做一個完整的介紹,但是在這之前,我們必須了解一些Jini架構中所定義的一些概念。以下就針對這些基本概念逐一解釋:
服務(Services)
在Jini架構中最重要的部份就是所謂的「服務」。所謂的服務,就是指任何一個人、程式、或是其他服務可以使用的單元。而一個服務,可以是一種運算,也可以是一種儲存媒介,甚至可以是一種和別人溝通的管道,或是軟體過濾程式、硬體設備、或是另一個使用者。舉例來說,我們列印文件的動作可以稱之為服務,而將文件由某種格式轉換成另一種格式,也可以稱之為一種服務。
所有在Jini系統中的使用者都可以共享系統所提供的服務,如果我們只將一群伺服器與客戶端視為一個Jini系統的話,這樣的想法並不適當。相反地,我們應該將Jini系統視為由一群服務所構成的環境,它們共同合作來提供某種特定的功能。所有的服務都可以供其他服務來使用,而某些服務的客戶端本身也可能擁有自己的客戶端。而Jini具有動態組織的天性更允許任何服務根據其需求,在任何時間加入或是退出整個系統,以提供適當的服務組合。
Jini系統提供了在分散式系統的環境中建構、找尋服務,同時也提供了服務之間的通訊管道。這類服務的例子有:設備部份包括印表機、顯示器、磁碟機,軟體部份包括應用程式以及工具程式,資訊的部份則包括資料庫以及檔案。其他如系統中的使用者等等。在Jini系統中,服務間的溝通是透過使用服務協定(service protocol)來完成的,而所謂的服務協定,是由Java程式語言所開發出來的一群程式界面,且這樣的一群協定是開放使用的。一個基本的Jini系統定義了一小組這樣的服務協定來提供服務間最重要的互動功能。
查詢服務(Lookup Services)
上節中所有的服務都是透過所謂的查詢服務來找尋及定位。查詢服務是Jini系統中最核心的起始功能,因為它建立了使用者和系統之間的橋樑。更精確的說,一個查詢服務的工作,就是將特定功能的服務所提供出來的介面,對應到系統中實際提供服務的伺服物件上。除此之外,服務中具有進一步敘述的屬性更可以提供專業的人仔細的選擇出更適合他們的服務。
在查詢服務中的物件也可以包含其他的查詢服務,也就是說,這提供了階層式的查詢模式。此外,一個查詢服務也可以包括其他的命名或目錄服務物件,藉此提供了和其他Jini查詢服務之間的橋樑,甚至對其他系統的查詢服務也可以達到相同的橋接能力。當然了,一個Jini的查詢服務的參考(reference)是可以放在這些其他的命名或是目錄服務中,以提供所服務的客戶端獲得另一個Jini系統中所提供的資源。一個服務可以透過一組發覺(discovery)以及加入(join)的協定來加入到一個查詢服務之中,其動作順序為:首先該服務會利用發覺協定來找出適當的查詢服務,其次便利用加入協定來將自己放入該查詢服務之中。
Java的遠端程序啟動(RMI)
在Jini系統中,服務之間的通訊都是透過Java的遠端程序啟動(也就是RMI)來完成。這樣的基礎架構不單只是提供服務之間的溝通方法而已,它更是整個Jini技術基礎架構的一部份。Java RMI提供了找尋以及啟動物件的方法,同時也提供了分散式的物件垃圾回收(Garbage Collection)功能。基本上,RMI是在Java程式語言環境中對傳統的遠端程序呼叫(Remote Procedure Call, RPC)所作的一種功能性的延伸。RMI不但允許資料在網路環境中由某物件傳送給另一個物件,同時更允許整個物件在網路中移動,其中當然包括了程式碼的部份。在Jini系統中這類的簡便性便是以RMI的能力為基礎,將程式碼以物件的形式在網路環境中傳遞。
安全性(Security)
在Jini技術中,安全模型的設計是由兩個方面角色來完成:一是當事人(principal),另一個則是存取控制名單(access control list)。Jini的服務是由所謂的當事人來存取,其中系統可以用當事人來回溯出系統中特定的使用者,而服務本身則是透過實作該服務的伺服物件來對外提供存取。至於是否具有存取服務的權限,則是由該物件本身所關連到的存取控制名單來予以決定。
租約(Leasing)
在Jini系統環境中,服務的存取是以租約(lease)為基礎的模式來提供。所謂的租約,是指在某段時間內,允許存取特定服務的特性。每一個租約都必須經過使用者、服務、以及服務提供者之間的協調,成為服務協定之中的一部份。使用者可能會需要在某段特定時間內使用某種服務,但真正允許存取的時間則不盡相同,服務本身需將請求的時間考慮在內後做出回應。如果某個租約到期,卻沒有做解約的動作的話,則使用者以及服務的提供者都可以假設租約已經終止,不論是因為該項資源已經不在需要使用,或是客戶端抑或網路發生了問題,甚至是租約不允許延續的情形都是如此。租約是可以有獨佔性的,但也可以不是,端看資源本身的特性來決定。所謂獨佔性的租約(exclusive lease),是指確保在使用資源的期間,沒有其他人可以租用這項資源(如列印服務)。而非獨佔性租約(non-exclusive lease)則允許多個使用者同時分享這項資源。
交易(Transactions)
所謂的交易,就是指一系列的運作(operation),不論這些運作是使用單一的服務,或是使用多個服務,都可以視為一項交易。Jini系統中的交易介面(Jini Transaction interface)提供了一個服務協定,用來執行一種兩階段式的運作(two-phase commit)。而交易本身的實作,包括交易本身所內含的意義,則留給使用交易介面的服務來予以規劃。
事件(Events)
Jini架構提供了分散式的事件模型(distributed event model)。一個物件可以允許其他物件針對特定的事件做登記,以便在稍後的運作中可以收到該事件發生的通知。這樣一來,便可以讓以分散式事件模型為基礎的程式擁有更具保障的可靠性以及擴展性。
Jini系統元件概觀
在Jini架構中,我們可以大略的將系統分成三大類元件,分別是基礎架構類、服務類、以及設計模型類。所謂的基礎架構類元件,就是指建立Jini系統環境所必需的建構單元。所謂的服務類元件,是指在系統環境中運作的單元,而設計模型類元件,則是指建立具有可靠性服務所需要的介面集合,其中包括屬於基礎架構的部份,以及在系統環境中運作的部份。雖然這三類元件具有相互獨立且各部相同的特性,但由於它們在系統中相互糾結,所以它們之間的差異也顯得有些模糊。此外,要建立一個Jini系統環境也不一定需要這三個部份同時存在。即使如此,一個Jini系統仍然可以發揮它的能力,因為它是由特殊的基礎架構和設計模型所構成,也就是我們所提到的“服務”。而在這樣的架構下區分出這三類元件,可以使得傳統的程式碼更動減至最低,進而順利的加入Jini系統的運作環境之中。但是,要Jini系統發揮它最大的能耐,還是必須要建立新的服務,並運用整合模式來建立時才會呈現。
我們可以將個完整的Jini系統,視為一個在單機上執行Java運作,並賦予在網路部份做上述的基礎架構、設計模型、以及服務的延伸。這幾類元件相對於原來的Java應用程式環境,我們可以由(表一)看出其中的差異之處。
基礎架構部份
在Jini的基礎架構下,定義了Jini技術最基本的核心功能。其基礎架構包含了以下幾個方面:
1. 一個分散式的安全模型,這些都已經整合在RMI之中,且延伸了原先Java平台的安全模型,使其在分散式系統的環境中運作。
2. 包含了發覺(discovery)以及加入(join)協定,服務協定允許各種服務(包含硬體以及軟體)去發掘其他服務,或是成為運作環境中的一員,甚至是通知其他成員自己所能提供的服務。
3. 內含查詢服務,也就是扮演了所有服務的倉庫管理,其中每個查詢服務的記錄(entry)都是由Java程式語言所設計出來的物件,這些物件是允許被下載的,成為查詢運作中的一部份,並同時擔任客戶端的代理者,負責與放在查詢服務處的程式碼進行溝通。
所謂的發覺及加入協定,就是用來定義將服務變為Jini系統中的一部份的方法,其中RMI是在Jini服務間擔任雙向溝通的角色。而分散式的安全模型以及其實作部份,則定義了系統中各組成份子該如何取得自己以及別人的使用權限。最後,查詢服務則反映了目前系統環境中所有成員的狀況,同時也扮演者為成員提供以及尋找服務的中央控制角色。
設計模型部份
Jini的基礎架構部份不但使用了設計模型,同時也善加利用了它。在查詢服務中的記錄部份,則是使用租約的方式來運作,這使得查詢服務得以正確地反映出目前所有可用的服務。而當有某些服務加入或是離開查詢服務的時候,就會發生相對應的通知事件,此時,其他系統中的物件便可以根據這個事件來得知是否有新的服務可用,或是不再提供哪些原有的服務。此外,設計模型的部份也具有移動程式碼的能力,因為這是在基本的基礎架構上就已經涵括的特點。
所有的基礎架構及架構在其上的服務都是可以執行運算的單元,共同存在Jini的運算環境中。此外,服務也是由一群定義溝通協定的介面所組成,而這些介面也可以供基礎架構或是其他服務來使用,提供相互之間的溝通管道。這些所謂的介面,共同組成了Java程式模型的分散是延伸版本,進而形成了Jini的程式設計環境。而這些形成Jini程式設計模型的介面有以下幾類:
1.和租約(leasing)相關的介面,這類介面定義了在可重複使用及具時間性的模型上配置即釋放資源的方法。
2.和事件(event)及通知(notifica- tion)相關的介面,這類介面是以JavaBeans元件的事件模型為基礎,將之延伸到分散式的環境中,用以提供Jini系統中服務之間的事件溝通管道。
3.和交易(transaction)相關的介面,這類介面可以使系統中各單元所造成的改變都可以確實對其他成員發生影響,或是完全沒有影響。
所謂和租約相關的介面,是將Java中有關持有對某些資源的參考模型,加上時間的因子,使得在網路發生問題時,這樣的參考持有可以安全的予以處理。而事件及通知相關的介面則延伸了原先Java-Beans元件以及Java應用程式環境的事件模型,使之能夠在分散式環境中運作,使得由其他物件所處理的事件可以確保遞送成功,而該模型也應該考慮到分散式的通知是有延遲的特性。
而在交易有關的介面部份,則引進了輕量化(light-weight)並具有物件導向特性的協定,使得Jini應用程式得以自由地控制自身在交易過程中狀態的變化。這種交易協定針對分散式物件的環境提供了一種協調期間動作的兩步驟做法,第一個步驟稱為投票階段(voting phase),在這期間每個物件均會根據本身是否完成自身工作的狀況來投票,而第二個步驟,則是協調者針對每一個物件發出執行完成的訊息,以達到交易完成的目的。
Jini的交易協定,和大多數的交易介面設計並不相同,這是因為Jini並不能假設系統中的交易是發生在標準的交易處理系統中,也就是說,它並不是處在一個能夠保證交易內容正確執行的環境中。相反地,Jini的交易協定採取了更接近傳統物件導向概念的觀點,將交易的正確內涵交付給涵括在交易中個別物件的實作方法,而整個交易協定的內容則是定義了這類物件在協調交易運作中所需的互動形式。
以上這些定義Jini設計模型的介面,都會用在基礎架構元件上,建構出最基本的Jini服務。例如,查詢服務使用了租約及事件相關的介面,租約協定能確保某些已登記服務的可用狀況,而事件介面則能針對管理上的問題以及設備組態動作上提供協助。又如Jini服務中的JavaSpace服務,是利用了租約及事件相關的介面,同時也支援Jini交易協定,所以交易管理者便可以藉以協調投票階段中所有參與其間的物件。請注意,並不是所有的服務都必須使用到Jini的設計模型,但是這樣的服務仍必須使用和Jini基礎架構互動的運作方法。例如,每個服務都必須使用設計模型和Jini的查詢服務交談,並且不論該服務所提供的資源是否需要使用到租約,它都必須和查詢服務本身之間有租約存在,且必須定期更新。
服務部份
Jini技術的基礎架構以及設計模型是共同用來在網路環境中提供以及找尋服務,而這些服務則是利用基礎架構來和其他服務進行溝通,或是找尋對方,以及告知其他服務及使用者自己的狀態。這些服務都是以Java程式語言所設計出來的物件形式存在,也有可能是使用其他物件所組成。一個典型的服務會提供一個介面,其中定義了該服務對外所能執行的運作,其中部份的介面可能是程式本身會使用到,也有一部份可能是由客戶端來執行,以達到服務和使用者之間溝通的目的。以下是一個Jini服務所包含的內容範例:
1.一個列印服務,可以由Java或傳統的應用程式執行列印的工作。
2.一個JavaSpace服務,這項服務是用來針對相關的Java物件,做簡單的溝通以及儲存資料之用。
3.一個交易管理程式,這個管理程式可以讓一群物件共同在Jini交易協定的環境中運作。
服務架構(Service Architecture)
服務形成了Jini系統中的溝通基礎,同時也是程式設計也是使用者的介面。關於服務的架構,最好是透過以下的Jini發覺以及查詢協定來進行了解。
發覺以及查詢協定
Jini系統的核心部份,是由發覺、加入以及查詢三個協定共同組成,其中發覺和加入協定是發生在設備要加入系統的時候。所謂的發覺動作,是當一個服務需要尋找欲登記的查詢服務時發生,而加入動作則是當查詢服務找到了以後所發生的行為。此外,查詢動作則是發生在當使用者需要符合某個介面型態的服務時發生。以下的運作步驟一(圖一)描述了發覺步驟的運作。
所謂的發覺以及加入運作,是將服務加入Jini系統的一個過程。而所謂服務的提供者,就是一個服務的起始點,如某個設備或是某個軟體程式。首先,服務提供者會先在區域網路上廣播一個請求,為的是找尋查詢服務的所在(如步驟一所示)。接著,相對於該服務的伺服物件便會被載入查詢服務之中(就是步驟二(圖二)的「加入」動作)。這個伺服物件包含了相對於該服務的Java程式語言介面,其中包括了使用者以及應用程式可以使用的方法,並伴隨著其他敘述性的屬性,藉以執行該項服務。此外,所有的服務,都必須有能力找到查詢服務。不過,一個服務也可以將這樣的事情委託給其他的服務來執行。無論如何,此時該服務就應該可以被其他人查詢到,並且提供他人使用,如步驟三(圖三)所示。在這樣的情形下,客戶端是根據服務的型態來定位該服務,也就是說,利用該服務所提供的Java定義介面,並伴隨著查詢服務所提供的其他敘述性屬性來決定。到了這裡,該伺服物件便可以載入客戶端以供執行。最後的一個步驟則是啟動該項服務,如步驟四(圖四)所示。
《圖二 服務提供者將伺服物件以及服務屬性登記在查詢服務中》 |
|
《圖三 客戶端根據型態以及其他屬性發出請求藉此取得一份相對應的伺服物件》 |
|
《圖四 客戶端透過伺服物件直接和服務提供者進行溝通》 |
|
這樣的伺服物件所內含的方法,其使用的通訊協定是可以自行定義的,因為所有通訊只在服務提供者及客戶端之間溝通。所以,提供相同介面的服務也可以使用完全不同的交談協定。
這種允許服務提供者透過查詢服務,將伺服物件的程式碼傳遞給客戶端的模式,提供了服務提供者絕大的彈性來設計自己的溝通模式。很熟悉嗎?沒錯,這和目前applet由伺服器傳遞到客戶端瀏覽器的模式的確有幾分神似。而這種移動程式碼的特性也可以確保伺服端所提供的服務可以正常的運作。因為在客戶端所執行的程式碼就相當於伺服物件的代理人一般。客戶端只需要了解到自身所使用的是由Java所撰寫的介面實作即可,所以介面的實作部份可以是任何服務所需要執行的工作。且由於程式碼是由服務本身所致做出來的,因此程式碼本身可以善用這樣的特性來予以發揮。
後記
本文介紹了在一個Jini系統中,服務是如何透過查詢服務來對外公開,同時也說明了客戶端如何透過查詢服務來取得特定服務的伺服物件供本身使用。而其間所使用的方法,就如同Java applet的特性一般,把伺服物件的程式碼由服務的提供者傳遞到客戶端本身,來做到所謂的服務代理人角色。這樣的模式,不但可以簡化主從式架構的設計,同時也可以因為伺服物件是由服務本身所撰寫的原因,實作出更為複雜的溝通協定,藉以提供更強大且複雜的服務內涵。